blob: e635eb88b3f1265ee8ba49ae0732036a856285e0 [file] [log] [blame]
/*
* Copyright (C) 2022 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.qns;
import static org.junit.Assert.*;
import android.content.Context;
import android.net.LinkProperties;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.os.test.TestLooper;
import android.telephony.AccessNetworkConstants;
import android.telephony.PreciseCallState;
import android.telephony.PreciseDataConnectionState;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@RunWith(JUnit4.class)
public class AlternativeEventListenerTest extends QnsTest {
AlternativeEventListener mListener;
AltEventProvider mAltEventProvider;
TestLooper mTestLooper;
private static final int SLOT_INDEX = 0;
private Handler mHandler;
CountDownLatch mLatch;
int[] mThresholds;
QnsTelephonyListener mQtListener;
class AltEventProvider extends AlternativeEventProvider {
AltEventProvider(Context context, int slotId) {
super(context, slotId);
}
@Override
public void requestRtpThreshold(
int callId,
int jitter,
int packetLossRate,
int packetLossTimeInMilliSec,
int noRtpTimeInMilliSec) {}
@Override
public void setEcnoSignalThreshold(int[] threshold) {
if (mLatch != null) {
mThresholds = threshold;
mLatch.countDown();
}
}
}
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
super.setUp();
mTestLooper = new TestLooper();
Mockito.when(sMockContext.getMainLooper()).thenReturn(mTestLooper.getLooper());
mHandler = new Handler(mTestLooper.getLooper());
mListener = AlternativeEventListener.getInstance(sMockContext, SLOT_INDEX);
mAltEventProvider = new AltEventProvider(sMockContext, SLOT_INDEX);
mQtListener = QnsTelephonyListener.getInstance(sMockContext, 0);
// mListener.setEventProvider(mAltEventProvider);
}
@After
public void tearDown() {
mQtListener.close();
mListener.close();
}
@Test
public void testRegisterEmergencyPreferredTransportTypeChanged() {
int[] expectedTransports =
new int[] {
AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
AccessNetworkConstants.TRANSPORT_TYPE_WWAN
};
mListener.registerEmergencyPreferredTransportTypeChanged(mHandler, 1, null);
for (int expectedTransport : expectedTransports) {
mAltEventProvider.notifyEmergencyPreferredTransportType(expectedTransport);
Message msg = mTestLooper.nextMessage();
assertNotNull(msg);
AsyncResult result = (AsyncResult) msg.obj;
assertNotNull(result.result);
int actualTransport = (int) result.result;
assertEquals(expectedTransport, actualTransport);
}
}
@Test
public void testUnregisterEmergencyPreferredTransportTypeChanged() {
mListener.registerEmergencyPreferredTransportTypeChanged(mHandler, 1, null);
mAltEventProvider.notifyEmergencyPreferredTransportType(
AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
Message msg = mTestLooper.nextMessage();
assertNotNull(msg);
mListener.unregisterEmergencyPreferredTransportTypeChanged();
mAltEventProvider.notifyEmergencyPreferredTransportType(
AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
msg = mTestLooper.nextMessage();
assertNull(msg);
mAltEventProvider.notifyEmergencyPreferredTransportType(
AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
msg = mTestLooper.nextMessage();
assertNull(msg);
}
@Test
public void testRegisterTryWfcConnectionStateListener() {
mListener.registerTryWfcConnectionStateListener(mHandler, 1, null);
boolean[] expectedStates = new boolean[] {false, true, false};
for (boolean expectedState : expectedStates) {
mAltEventProvider.notifyTryWfcConnectionState(expectedState);
Message msg = mTestLooper.nextMessage();
assertNotNull(msg);
AsyncResult result = (AsyncResult) msg.obj;
assertNotNull(result.result);
boolean actualState = (boolean) result.result;
assertEquals(expectedState, actualState);
}
}
@Test
public void testForRtpQualityScenarios() {
QnsCarrierConfigManager.RtpMetricsConfig rtpConfig =
new QnsCarrierConfigManager.RtpMetricsConfig(0, 0, 0, 0);
int expectedReason = QnsConstants.RTP_LOW_QUALITY_REASON_JITTER;
// register to IMS, Emergency:
mListener.registerLowRtpQualityEvent(ApnSetting.TYPE_IMS, mHandler, 1, null, rtpConfig);
mListener.registerLowRtpQualityEvent(
ApnSetting.TYPE_EMERGENCY, mHandler, 2, null, rtpConfig);
mAltEventProvider.notifyCallInfo(
1, QnsConstants.CALL_TYPE_VOICE, PreciseCallState.PRECISE_CALL_STATE_ACTIVE);
mAltEventProvider.notifyRtpLowQuality(expectedReason);
Message msg = mTestLooper.nextMessage();
assertNotNull(msg);
AsyncResult result = (AsyncResult) msg.obj;
assertNotNull(result.result);
int actualReason = (int) result.result;
assertEquals(expectedReason, actualReason);
// Do not notify when call is disconnected:
mAltEventProvider.notifyCallInfo(
1, QnsConstants.CALL_TYPE_VOICE, PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED);
mAltEventProvider.notifyRtpLowQuality(expectedReason);
msg = mTestLooper.nextMessage();
assertNull(msg);
mAltEventProvider.notifyCallInfo(
2, QnsConstants.CALL_TYPE_EMERGENCY, PreciseCallState.PRECISE_CALL_STATE_ACTIVE);
mAltEventProvider.notifyRtpLowQuality(expectedReason);
msg = mTestLooper.nextMessage();
assertNotNull(msg);
result = (AsyncResult) msg.obj;
assertNotNull(result.result);
actualReason = (int) result.result;
assertEquals(expectedReason, actualReason);
// Do not notify when call is disconnected:
mAltEventProvider.notifyCallInfo(
1,
QnsConstants.CALL_TYPE_EMERGENCY,
PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED);
mAltEventProvider.notifyRtpLowQuality(expectedReason);
msg = mTestLooper.nextMessage();
assertNull(msg);
}
@Test
public void testUnregisterLowRtpQualityEvent() {
QnsCarrierConfigManager.RtpMetricsConfig rtpConfig =
new QnsCarrierConfigManager.RtpMetricsConfig(0, 0, 0, 0);
int expectedReason = QnsConstants.RTP_LOW_QUALITY_REASON_JITTER;
mAltEventProvider.notifyCallInfo(
1, QnsConstants.CALL_TYPE_VOICE, PreciseCallState.PRECISE_CALL_STATE_ACTIVE);
// register to IMS, Emergency:
mListener.registerLowRtpQualityEvent(ApnSetting.TYPE_IMS, mHandler, 1, null, rtpConfig);
mListener.registerLowRtpQualityEvent(
ApnSetting.TYPE_EMERGENCY, mHandler, 2, null, rtpConfig);
mAltEventProvider.notifyRtpLowQuality(expectedReason);
Message msg = mTestLooper.nextMessage();
assertNotNull(msg);
// unregister for IMS
mListener.unregisterLowRtpQualityEvent(ApnSetting.TYPE_IMS, mHandler);
mAltEventProvider.notifyRtpLowQuality(expectedReason);
msg = mTestLooper.nextMessage();
assertNull(msg);
// Event still registered for emergency, hence it should be notified:
mAltEventProvider.notifyCallInfo(
1, QnsConstants.CALL_TYPE_EMERGENCY, PreciseCallState.PRECISE_CALL_STATE_ACTIVE);
mAltEventProvider.notifyRtpLowQuality(expectedReason);
msg = mTestLooper.nextMessage();
assertNotNull(msg);
// unregister for Emergency:
mListener.unregisterLowRtpQualityEvent(ApnSetting.TYPE_EMERGENCY, mHandler);
mAltEventProvider.notifyRtpLowQuality(expectedReason);
msg = mTestLooper.nextMessage();
assertNull(msg);
}
@Test
public void testForCallTypeChangedScenarios() {
mListener.registerCallTypeChangedListener(ApnSetting.TYPE_IMS, null, 1, null);
mListener.registerCallTypeChangedListener(ApnSetting.TYPE_IMS, mHandler, 1, null);
mListener.registerCallTypeChangedListener(ApnSetting.TYPE_EMERGENCY, mHandler, 1, null);
mListener.registerCallTypeChangedListener(ApnSetting.TYPE_MMS, mHandler, 1, null);
// Test1:
mAltEventProvider.notifyCallInfo(
1, QnsConstants.CALL_TYPE_VOICE, PreciseCallState.PRECISE_CALL_STATE_ACTIVE);
Message msg = mTestLooper.nextMessage();
assertNotNull(msg);
AsyncResult result = (AsyncResult) msg.obj;
assertNotNull(result.result);
assertEquals(QnsConstants.CALL_TYPE_VOICE, (int) result.result);
assertFalse(mListener.isIdleState()); // for IMS calls only
// Test2:
mAltEventProvider.notifyCallInfo(
1, QnsConstants.CALL_TYPE_VOICE, PreciseCallState.PRECISE_CALL_STATE_ACTIVE);
msg = mTestLooper.nextMessage();
// Should not notify if call type is not changed
assertNull(msg);
// Test3:
mAltEventProvider.notifyCallInfo(
1, QnsConstants.CALL_TYPE_VOICE, PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED);
msg = mTestLooper.nextMessage();
assertNotNull(msg);
result = (AsyncResult) msg.obj;
assertNotNull(result.result);
assertEquals(QnsConstants.CALL_TYPE_IDLE, (int) result.result);
assertTrue(mListener.isIdleState()); // for IMS calls only
// Test4:
mAltEventProvider.notifyCallInfo(
2, QnsConstants.CALL_TYPE_EMERGENCY, PreciseCallState.PRECISE_CALL_STATE_ACTIVE);
msg = mTestLooper.nextMessage();
assertNotNull(msg);
result = (AsyncResult) msg.obj;
assertNotNull(result.result);
assertEquals(QnsConstants.CALL_TYPE_EMERGENCY, (int) result.result);
// Test5:
mAltEventProvider.notifyCallInfo(
2,
QnsConstants.CALL_TYPE_EMERGENCY,
PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED);
msg = mTestLooper.nextMessage();
assertNotNull(msg);
result = (AsyncResult) msg.obj;
assertNotNull(result.result);
assertEquals(QnsConstants.CALL_TYPE_IDLE, (int) result.result);
}
@Test
public void testUnregisterCallTypeChangedListener() {
mListener.registerCallTypeChangedListener(ApnSetting.TYPE_IMS, null, 1, null);
mListener.registerCallTypeChangedListener(ApnSetting.TYPE_IMS, mHandler, 1, null);
mListener.registerCallTypeChangedListener(ApnSetting.TYPE_EMERGENCY, mHandler, 1, null);
mListener.registerCallTypeChangedListener(ApnSetting.TYPE_MMS, mHandler, 1, null);
mAltEventProvider.notifyCallInfo(
1, QnsConstants.CALL_TYPE_VOICE, PreciseCallState.PRECISE_CALL_STATE_ACTIVE);
Message msg = mTestLooper.nextMessage();
assertNotNull(msg);
mListener.unregisterCallTypeChangedListener(ApnSetting.TYPE_IMS, mHandler);
mAltEventProvider.notifyCallInfo(
1, QnsConstants.CALL_TYPE_VOICE, PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED);
msg = mTestLooper.nextMessage();
assertNull(msg);
mAltEventProvider.notifyCallInfo(
1, QnsConstants.CALL_TYPE_EMERGENCY, PreciseCallState.PRECISE_CALL_STATE_ACTIVE);
msg = mTestLooper.nextMessage();
assertNotNull(msg);
mListener.unregisterCallTypeChangedListener(ApnSetting.TYPE_EMERGENCY, mHandler);
mAltEventProvider.notifyCallInfo(
1,
QnsConstants.CALL_TYPE_EMERGENCY,
PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED);
msg = mTestLooper.nextMessage();
assertNull(msg);
}
@Test
public void testEmergencyOverImsCallTypeChangedScenarios() {
mListener.registerCallTypeChangedListener(ApnSetting.TYPE_IMS, mHandler, 1, null);
PreciseDataConnectionState emergencyDataStatus =
new PreciseDataConnectionState.Builder()
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_INVALID)
.setState(TelephonyManager.DATA_DISCONNECTED)
.setNetworkType(AccessNetworkConstants.AccessNetworkType.EUTRAN)
.setApnSetting(
new ApnSetting.Builder()
.setApnTypeBitmask(ApnSetting.TYPE_EMERGENCY)
.setApnName("sos")
.setEntryName("sos")
.build())
.setLinkProperties(new LinkProperties())
.build();
PreciseDataConnectionState imsDataStatus =
new PreciseDataConnectionState.Builder()
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
.setState(TelephonyManager.DATA_CONNECTED)
.setNetworkType(AccessNetworkConstants.AccessNetworkType.IWLAN)
.setApnSetting(
new ApnSetting.Builder()
.setApnTypeBitmask(ApnSetting.TYPE_IMS)
.setApnName("ims")
.setEntryName("ims")
.build())
.build();
mQtListener.mTelephonyListener.onPreciseDataConnectionStateChanged(emergencyDataStatus);
mQtListener.mTelephonyListener.onPreciseDataConnectionStateChanged(imsDataStatus);
// Test1:
mAltEventProvider.notifyCallInfo(
1, QnsConstants.CALL_TYPE_EMERGENCY, PreciseCallState.PRECISE_CALL_STATE_DIALING);
Message msg = mTestLooper.nextMessage();
assertNotNull(msg);
AsyncResult result = (AsyncResult) msg.obj;
assertNotNull(result.result);
assertEquals(QnsConstants.CALL_TYPE_EMERGENCY, (int) result.result);
// Test2:
mAltEventProvider.notifyCallInfo(
1, QnsConstants.CALL_TYPE_EMERGENCY, PreciseCallState.PRECISE_CALL_STATE_ACTIVE);
msg = mTestLooper.nextMessage();
// Should not notify if call type is not changed
assertNull(msg);
// Test3:
imsDataStatus =
new PreciseDataConnectionState.Builder()
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_INVALID)
.setState(TelephonyManager.DATA_DISCONNECTED)
.setNetworkType(AccessNetworkConstants.AccessNetworkType.EUTRAN)
.setApnSetting(
new ApnSetting.Builder()
.setApnTypeBitmask(ApnSetting.TYPE_IMS)
.setApnName("ims")
.setEntryName("ims")
.build())
.build();
mQtListener.mTelephonyListener.onPreciseDataConnectionStateChanged(imsDataStatus);
mAltEventProvider.notifyCallInfo(
1,
QnsConstants.CALL_TYPE_EMERGENCY,
PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED);
msg = mTestLooper.nextMessage();
assertNotNull(msg);
result = (AsyncResult) msg.obj;
assertNotNull(result.result);
assertEquals(QnsConstants.CALL_TYPE_IDLE, (int) result.result);
// Test4:
emergencyDataStatus =
new PreciseDataConnectionState.Builder()
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
.setState(TelephonyManager.DATA_CONNECTED)
.setNetworkType(AccessNetworkConstants.AccessNetworkType.IWLAN)
.setApnSetting(
new ApnSetting.Builder()
.setApnTypeBitmask(ApnSetting.TYPE_EMERGENCY)
.setApnName("sos")
.setEntryName("sos")
.build())
.build();
mQtListener.mTelephonyListener.onPreciseDataConnectionStateChanged(emergencyDataStatus);
imsDataStatus =
new PreciseDataConnectionState.Builder()
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
.setState(TelephonyManager.DATA_CONNECTED)
.setNetworkType(AccessNetworkConstants.AccessNetworkType.IWLAN)
.setApnSetting(
new ApnSetting.Builder()
.setApnTypeBitmask(ApnSetting.TYPE_IMS)
.setApnName("ims")
.setEntryName("ims")
.build())
.build();
mQtListener.mTelephonyListener.onPreciseDataConnectionStateChanged(imsDataStatus);
mAltEventProvider.notifyCallInfo(
2, QnsConstants.CALL_TYPE_EMERGENCY, PreciseCallState.PRECISE_CALL_STATE_ACTIVE);
msg = mTestLooper.nextMessage();
assertNull(msg);
}
@Test
public void testOnSrvccStateChanged() {
mListener.registerCallTypeChangedListener(ApnSetting.TYPE_IMS, mHandler, 1, null);
mListener.onSrvccStateChanged(TelephonyManager.SRVCC_STATE_HANDOVER_COMPLETED);
Message msg = mTestLooper.nextMessage();
assertNotNull(msg);
AsyncResult result = (AsyncResult) msg.obj;
assertNotNull(result.result);
assertEquals(QnsConstants.CALL_TYPE_IDLE, (int) result.result);
mListener.onSrvccStateChanged(TelephonyManager.SRVCC_STATE_HANDOVER_STARTED);
msg = mTestLooper.nextMessage();
assertNull(msg);
}
@Test
public void isIdleState() {
mListener.isIdleState();
}
@Test
public void setEcnoSignalThreshold() throws InterruptedException {
mLatch = new CountDownLatch(1);
int[] ecnoThresholds = new int[] {-85, -90, -95};
mListener.setEcnoSignalThreshold(ecnoThresholds);
assertTrue(mLatch.await(100, TimeUnit.MILLISECONDS));
assertNotNull(mThresholds);
assertArrayEquals(ecnoThresholds, mThresholds);
}
}