1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.telephony.qns; 18 19 import static org.junit.Assert.assertTrue; 20 import static org.junit.Assert.fail; 21 import static org.mockito.ArgumentMatchers.anyInt; 22 import static org.mockito.ArgumentMatchers.anyString; 23 import static org.mockito.Mockito.spy; 24 import static org.mockito.Mockito.when; 25 26 import android.content.Context; 27 import android.content.pm.PackageManager; 28 import android.content.res.Resources; 29 import android.location.Country; 30 import android.location.CountryDetector; 31 import android.net.ConnectivityManager; 32 import android.net.wifi.WifiInfo; 33 import android.net.wifi.WifiManager; 34 import android.os.Handler; 35 import android.os.PowerManager; 36 import android.telephony.CarrierConfigManager; 37 import android.telephony.SubscriptionInfo; 38 import android.telephony.SubscriptionManager; 39 import android.telephony.TelephonyManager; 40 import android.telephony.ims.ImsManager; 41 import android.telephony.ims.ImsMmTelManager; 42 import android.telephony.ims.ImsRcsManager; 43 import android.telephony.ims.SipDelegateManager; 44 45 import androidx.test.core.app.ApplicationProvider; 46 47 import org.mockito.Mock; 48 49 import java.lang.reflect.Field; 50 import java.util.concurrent.CountDownLatch; 51 import java.util.concurrent.TimeUnit; 52 53 public abstract class QnsTest { 54 private static final long MAX_WAIT_TIME_MS = 10000; 55 @Mock protected static Context sMockContext; 56 57 @Mock protected TelephonyManager mMockTelephonyManager; 58 @Mock protected CarrierConfigManager mMockCarrierConfigManager; 59 @Mock protected ConnectivityManager mMockConnectivityManager; 60 @Mock protected ImsManager mMockImsManager; 61 @Mock protected SubscriptionManager mMockSubscriptionManager; 62 @Mock protected WifiManager mMockWifiManager; 63 @Mock protected CountryDetector mMockCountryDetector; 64 65 @Mock protected ImsMmTelManager mMockImsMmTelManager; 66 @Mock protected ImsRcsManager mMockImsRcsManager; 67 @Mock protected SipDelegateManager mMockSipDelegateManager; 68 @Mock protected SubscriptionInfo mMockSubscriptionInfo; 69 @Mock protected WifiInfo mMockWifiInfo; 70 @Mock protected Resources mMockResources; 71 72 // qns mocks 73 @Mock protected IwlanNetworkStatusTracker mMockIwlanNetworkStatusTracker; 74 @Mock protected WifiQualityMonitor mMockWifiQm; 75 @Mock protected CellularNetworkStatusTracker mMockCellNetStatusTracker; 76 @Mock protected CellularQualityMonitor mMockCellularQm; 77 @Mock protected PowerManager mMockPowerManager; 78 @Mock protected QnsImsManager mMockQnsImsManager; 79 @Mock protected QnsCarrierConfigManager mMockQnsConfigManager; 80 @Mock protected QnsEventDispatcher mMockQnsEventDispatcher; 81 @Mock protected QnsProvisioningListener mMockQnsProvisioningListener; 82 @Mock protected QnsTelephonyListener mMockQnsTelephonyListener; 83 @Mock protected QnsCallStatusTracker mMockQnsCallStatusTracker; 84 @Mock protected WifiBackhaulMonitor mMockWifiBm; 85 @Mock protected QnsTimer mMockQnsTimer; 86 @Mock protected QnsMetrics mMockQnsMetrics; 87 88 protected QnsComponents[] mQnsComponents = new QnsComponents[2]; 89 90 private boolean mReady = false; 91 private final Object mLock = new Object(); 92 setUp()93 protected void setUp() throws Exception { 94 sMockContext = spy(ApplicationProvider.getApplicationContext()); 95 stubContext(); 96 stubManagers(); 97 stubOthers(); 98 stubQnsComponents(); 99 addPermissions(); 100 } 101 stubQnsComponents()102 private void stubQnsComponents() { 103 mQnsComponents[0] = 104 new QnsComponents( 105 sMockContext, 106 mMockCellNetStatusTracker, 107 mMockCellularQm, 108 mMockIwlanNetworkStatusTracker, 109 mMockQnsImsManager, 110 mMockQnsConfigManager, 111 mMockQnsEventDispatcher, 112 mMockQnsProvisioningListener, 113 mMockQnsTelephonyListener, 114 mMockQnsCallStatusTracker, 115 mMockQnsTimer, 116 mMockWifiBm, 117 mMockWifiQm, 118 mMockQnsMetrics, 119 0); 120 121 mQnsComponents[1] = 122 new QnsComponents( 123 sMockContext, 124 mMockCellNetStatusTracker, 125 mMockCellularQm, 126 mMockIwlanNetworkStatusTracker, 127 mMockQnsImsManager, 128 mMockQnsConfigManager, 129 mMockQnsEventDispatcher, 130 mMockQnsProvisioningListener, 131 mMockQnsTelephonyListener, 132 mMockQnsCallStatusTracker, 133 mMockQnsTimer, 134 mMockWifiBm, 135 mMockWifiQm, 136 mMockQnsMetrics, 137 1); 138 } 139 stubContext()140 private void stubContext() { 141 when(sMockContext.getSystemService(TelephonyManager.class)) 142 .thenReturn(mMockTelephonyManager); 143 when(sMockContext.getSystemService(SubscriptionManager.class)) 144 .thenReturn(mMockSubscriptionManager); 145 when(sMockContext.getSystemService(CarrierConfigManager.class)) 146 .thenReturn(mMockCarrierConfigManager); 147 when(sMockContext.getSystemService(ConnectivityManager.class)) 148 .thenReturn(mMockConnectivityManager); 149 when(sMockContext.getSystemService(ImsManager.class)).thenReturn(mMockImsManager); 150 when(sMockContext.getSystemService(WifiManager.class)).thenReturn(mMockWifiManager); 151 when(sMockContext.getSystemService(CountryDetector.class)).thenReturn(mMockCountryDetector); 152 when(sMockContext.getSystemService(PowerManager.class)).thenReturn(mMockPowerManager); 153 when(sMockContext.getResources()).thenReturn(mMockResources); 154 } 155 stubManagers()156 private void stubManagers() { 157 when(mMockTelephonyManager.createForSubscriptionId(anyInt())) 158 .thenReturn(mMockTelephonyManager); 159 when(mMockTelephonyManager.getSimCarrierId()).thenReturn(0); 160 when(mMockTelephonyManager.getSimCountryIso()).thenReturn("ca"); 161 when(mMockImsManager.getImsMmTelManager(anyInt())).thenReturn(mMockImsMmTelManager); 162 when(mMockImsManager.getImsRcsManager(anyInt())).thenReturn(mMockImsRcsManager); 163 when(mMockImsManager.getSipDelegateManager(anyInt())).thenReturn(mMockSipDelegateManager); 164 when(mMockSubscriptionManager.getActiveSubscriptionInfo(anyInt())) 165 .thenReturn(mMockSubscriptionInfo); 166 when(mMockSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(anyInt())) 167 .thenReturn(mMockSubscriptionInfo); 168 169 when(mMockWifiManager.getConnectionInfo()).thenReturn(mMockWifiInfo); 170 171 when(mMockCountryDetector.detectCountry()) 172 .thenReturn(new Country("US", Country.COUNTRY_SOURCE_LOCATION)); 173 when(mMockPowerManager.isDeviceIdleMode()).thenReturn(false); 174 } 175 stubOthers()176 private void stubOthers() { 177 when(mMockWifiInfo.getRssi()).thenReturn(-65); 178 } 179 addPermissions()180 private void addPermissions() { 181 when(sMockContext.checkPermission(anyString(), anyInt(), anyInt())) 182 .thenReturn(PackageManager.PERMISSION_GRANTED); 183 } 184 waitUntilReady()185 protected void waitUntilReady() { 186 synchronized (mLock) { 187 if (!mReady) { 188 try { 189 mLock.wait(MAX_WAIT_TIME_MS); 190 } catch (InterruptedException e) { 191 } 192 if (!mReady) { 193 fail("Test is not ready!!"); 194 } 195 } 196 } 197 } 198 199 /** Wait for up to 2 second for the handler message queue to clear. */ waitForLastHandlerAction(Handler h)200 protected final void waitForLastHandlerAction(Handler h) { 201 CountDownLatch lock = new CountDownLatch(1); 202 // Allow the handler to start work on stuff. 203 h.postDelayed(lock::countDown, 100); 204 int timeoutCount = 0; 205 while (timeoutCount < 10) { 206 try { 207 if (lock.await(200, TimeUnit.MILLISECONDS)) { 208 // no messages in queue, stop waiting. 209 if (!h.hasMessagesOrCallbacks()) break; 210 lock = new CountDownLatch(1); 211 // Delay allowing the handler thread to start work on stuff. 212 h.postDelayed(lock::countDown, 100); 213 } 214 } catch (InterruptedException e) { 215 // do nothing 216 } 217 timeoutCount++; 218 } 219 assertTrue("Handler was not empty before timeout elapsed", timeoutCount < 10); 220 } 221 waitForDelayedHandlerAction( Handler h, long delayMillis, long timeoutMillis)222 protected final void waitForDelayedHandlerAction( 223 Handler h, long delayMillis, long timeoutMillis) { 224 final CountDownLatch lock = new CountDownLatch(1); 225 h.postDelayed(lock::countDown, delayMillis); 226 while (lock.getCount() > 0) { 227 try { 228 lock.await(delayMillis + timeoutMillis, TimeUnit.MILLISECONDS); 229 } catch (InterruptedException e) { 230 // do nothing 231 } 232 } 233 } 234 setReady(boolean ready)235 protected void setReady(boolean ready) { 236 synchronized (mLock) { 237 mReady = ready; 238 mLock.notifyAll(); 239 } 240 } 241 setObject( final Class c, final String field, final Object obj, final Object newValue)242 protected synchronized void setObject( 243 final Class c, final String field, final Object obj, final Object newValue) 244 throws Exception { 245 Field f = c.getDeclaredField(field); 246 f.setAccessible(true); 247 f.set(obj, newValue); 248 } 249 } 250