blob: b2eddc38116985d9a9815734574232e0067626b1 [file] [log] [blame]
/*
* Copyright (C) 2016 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;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.nullable;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.spy;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.IActivityManager;
import android.app.KeyguardManager;
import android.app.usage.NetworkStatsManager;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.content.IIntentSender;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.net.NetworkPolicyManager;
import android.net.vcn.VcnManager;
import android.net.vcn.VcnNetworkPolicyResult;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.MessageQueue;
import android.os.RegistrantList;
import android.os.ServiceManager;
import android.os.StrictMode;
import android.os.UserManager;
import android.permission.LegacyPermissionManager;
import android.provider.BlockedNumberContract;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.provider.Telephony;
import android.telephony.AccessNetworkConstants;
import android.telephony.CarrierConfigManager;
import android.telephony.CellIdentity;
import android.telephony.CellLocation;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyRegistryManager;
import android.telephony.emergency.EmergencyNumber;
import android.telephony.euicc.EuiccManager;
import android.telephony.ims.ImsCallProfile;
import android.test.mock.MockContentProvider;
import android.test.mock.MockContentResolver;
import android.testing.TestableLooper;
import android.util.Log;
import android.util.Singleton;
import com.android.ims.ImsCall;
import com.android.ims.ImsEcbm;
import com.android.ims.ImsManager;
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
import com.android.internal.telephony.cdma.EriManager;
import com.android.internal.telephony.data.AccessNetworksManager;
import com.android.internal.telephony.data.CellularNetworkValidator;
import com.android.internal.telephony.data.DataConfigManager;
import com.android.internal.telephony.data.DataEnabledOverride;
import com.android.internal.telephony.data.DataNetworkController;
import com.android.internal.telephony.data.DataProfileManager;
import com.android.internal.telephony.data.DataRetryManager;
import com.android.internal.telephony.data.DataServiceManager;
import com.android.internal.telephony.data.DataSettingsManager;
import com.android.internal.telephony.data.LinkBandwidthEstimator;
import com.android.internal.telephony.dataconnection.DataEnabledSettings;
import com.android.internal.telephony.dataconnection.DataThrottler;
import com.android.internal.telephony.dataconnection.DcTracker;
import com.android.internal.telephony.emergency.EmergencyNumberTracker;
import com.android.internal.telephony.imsphone.ImsExternalCallTracker;
import com.android.internal.telephony.imsphone.ImsPhone;
import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
import com.android.internal.telephony.metrics.ImsStats;
import com.android.internal.telephony.metrics.MetricsCollector;
import com.android.internal.telephony.metrics.PersistAtomsStorage;
import com.android.internal.telephony.metrics.SmsStats;
import com.android.internal.telephony.metrics.VoiceCallSessionStats;
import com.android.internal.telephony.test.SimulatedCommands;
import com.android.internal.telephony.test.SimulatedCommandsVerifier;
import com.android.internal.telephony.uicc.IccCardStatus;
import com.android.internal.telephony.uicc.IccRecords;
import com.android.internal.telephony.uicc.IsimUiccRecords;
import com.android.internal.telephony.uicc.PinStorage;
import com.android.internal.telephony.uicc.RuimRecords;
import com.android.internal.telephony.uicc.SIMRecords;
import com.android.internal.telephony.uicc.UiccCard;
import com.android.internal.telephony.uicc.UiccCardApplication;
import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.telephony.uicc.UiccPort;
import com.android.internal.telephony.uicc.UiccProfile;
import com.android.internal.telephony.uicc.UiccSlot;
import com.android.server.pm.permission.LegacyPermissionManagerService;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public abstract class TelephonyTest {
protected static String TAG;
private static final int MAX_INIT_WAIT_MS = 30000; // 30 seconds
private static final EmergencyNumber SAMPLE_EMERGENCY_NUMBER =
new EmergencyNumber("911", "us", "30",
EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
new ArrayList<String>(), EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
private static final Field MESSAGE_QUEUE_FIELD;
private static final Field MESSAGE_WHEN_FIELD;
private static final Field MESSAGE_NEXT_FIELD;
static {
try {
MESSAGE_QUEUE_FIELD = MessageQueue.class.getDeclaredField("mMessages");
MESSAGE_QUEUE_FIELD.setAccessible(true);
MESSAGE_WHEN_FIELD = Message.class.getDeclaredField("when");
MESSAGE_WHEN_FIELD.setAccessible(true);
MESSAGE_NEXT_FIELD = Message.class.getDeclaredField("next");
MESSAGE_NEXT_FIELD.setAccessible(true);
} catch (NoSuchFieldException e) {
throw new RuntimeException("Failed to initialize TelephonyTest", e);
}
}
// Mocked classes
protected GsmCdmaPhone mPhone;
protected ImsPhone mImsPhone;
protected ServiceStateTracker mSST;
protected EmergencyNumberTracker mEmergencyNumberTracker;
protected GsmCdmaCallTracker mCT;
protected ImsPhoneCallTracker mImsCT;
protected UiccController mUiccController;
protected UiccProfile mUiccProfile;
protected CallManager mCallManager;
protected PhoneNotifier mNotifier;
protected TelephonyComponentFactory mTelephonyComponentFactory;
protected CdmaSubscriptionSourceManager mCdmaSSM;
protected RegistrantList mRegistrantList;
protected IccPhoneBookInterfaceManager mIccPhoneBookIntManager;
protected ImsManager mImsManager;
protected DcTracker mDcTracker;
protected DataNetworkController mDataNetworkController;
protected DataRetryManager mDataRetryManager;
protected DataSettingsManager mDataSettingsManager;
protected DataConfigManager mDataConfigManager;
protected DataProfileManager mDataProfileManager;
protected DisplayInfoController mDisplayInfoController;
protected GsmCdmaCall mGsmCdmaCall;
protected ImsCall mImsCall;
protected ImsEcbm mImsEcbm;
protected SubscriptionController mSubscriptionController;
protected ServiceState mServiceState;
protected IPackageManager.Stub mMockPackageManager;
protected LegacyPermissionManagerService mMockLegacyPermissionManager;
protected SimulatedCommandsVerifier mSimulatedCommandsVerifier;
protected InboundSmsHandler mInboundSmsHandler;
protected WspTypeDecoder mWspTypeDecoder;
protected UiccCardApplication mUiccCardApplication3gpp;
protected UiccCardApplication mUiccCardApplication3gpp2;
protected UiccCardApplication mUiccCardApplicationIms;
protected SIMRecords mSimRecords;
protected RuimRecords mRuimRecords;
protected IsimUiccRecords mIsimUiccRecords;
protected ProxyController mProxyController;
protected Singleton<IActivityManager> mIActivityManagerSingleton;
protected IActivityManager mIActivityManager;
protected IIntentSender mIIntentSender;
protected IBinder mIBinder;
protected SmsStorageMonitor mSmsStorageMonitor;
protected SmsUsageMonitor mSmsUsageMonitor;
protected PackageInfo mPackageInfo;
protected ApplicationInfo mApplicationInfo;
protected EriManager mEriManager;
protected IBinder mConnMetLoggerBinder;
protected CarrierSignalAgent mCarrierSignalAgent;
protected CarrierActionAgent mCarrierActionAgent;
protected ImsExternalCallTracker mImsExternalCallTracker;
protected AppSmsManager mAppSmsManager;
protected IccSmsInterfaceManager mIccSmsInterfaceManager;
protected SmsDispatchersController mSmsDispatchersController;
protected DeviceStateMonitor mDeviceStateMonitor;
protected AccessNetworksManager mAccessNetworksManager;
protected IntentBroadcaster mIntentBroadcaster;
protected NitzStateMachine mNitzStateMachine;
protected RadioConfig mMockRadioConfig;
protected SubscriptionInfoUpdater mSubInfoRecordUpdater;
protected LocaleTracker mLocaleTracker;
protected RestrictedState mRestrictedState;
protected DataEnabledSettings mDataEnabledSettings;
protected DataEnabledOverride mDataEnabledOverride;
protected PhoneConfigurationManager mPhoneConfigurationManager;
protected CellularNetworkValidator mCellularNetworkValidator;
protected UiccCard mUiccCard;
protected UiccPort mUiccPort;
protected MultiSimSettingController mMultiSimSettingController;
protected IccCard mIccCard;
protected NetworkStatsManager mStatsManager;
protected CarrierPrivilegesTracker mCarrierPrivilegesTracker;
protected VoiceCallSessionStats mVoiceCallSessionStats;
protected PersistAtomsStorage mPersistAtomsStorage;
protected MetricsCollector mMetricsCollector;
protected SmsStats mSmsStats;
protected DataThrottler mDataThrottler;
protected SignalStrength mSignalStrength;
protected WifiManager mWifiManager;
protected WifiInfo mWifiInfo;
protected ImsStats mImsStats;
protected LinkBandwidthEstimator mLinkBandwidthEstimator;
protected PinStorage mPinStorage;
protected LocationManager mLocationManager;
protected CellIdentity mCellIdentity;
protected CellLocation mCellLocation;
protected DataServiceManager mMockedWwanDataServiceManager;
protected DataServiceManager mMockedWlanDataServiceManager;
// Initialized classes
protected ActivityManager mActivityManager;
protected ImsCallProfile mImsCallProfile;
protected TelephonyManager mTelephonyManager;
protected TelephonyRegistryManager mTelephonyRegistryManager;
protected SubscriptionManager mSubscriptionManager;
protected EuiccManager mEuiccManager;
protected PackageManager mPackageManager;
protected ConnectivityManager mConnectivityManager;
protected AppOpsManager mAppOpsManager;
protected CarrierConfigManager mCarrierConfigManager;
protected UserManager mUserManager;
protected KeyguardManager mKeyguardManager;
protected VcnManager mVcnManager;
protected NetworkPolicyManager mNetworkPolicyManager;
protected SimulatedCommands mSimulatedCommands;
protected ContextFixture mContextFixture;
protected Context mContext;
protected FakeBlockedNumberContentProvider mFakeBlockedNumberContentProvider;
private final ContentProvider mContentProvider = spy(new ContextFixture.FakeContentProvider());
private Object mLock = new Object();
private boolean mReady;
protected HashMap<String, IBinder> mServiceManagerMockedServices = new HashMap<>();
protected Phone[] mPhones;
protected NetworkRegistrationInfo mNetworkRegistrationInfo =
new NetworkRegistrationInfo.Builder()
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
.setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
.build();
protected List<TestableLooper> mTestableLoopers = new ArrayList<>();
protected TestableLooper mTestableLooper;
private final HashMap<InstanceKey, Object> mOldInstances = new HashMap<>();
private final LinkedList<InstanceKey> mInstanceKeys = new LinkedList<>();
private class InstanceKey {
public final Class mClass;
public final String mInstName;
public final Object mObj;
InstanceKey(final Class c, final String instName, final Object obj) {
mClass = c;
mInstName = instName;
mObj = obj;
}
@Override
public int hashCode() {
return (mClass.getName().hashCode() * 31 + mInstName.hashCode()) * 31;
}
@Override
public boolean equals(Object obj) {
if (obj == null || obj.getClass() != getClass()) {
return false;
}
InstanceKey other = (InstanceKey) obj;
return (other.mClass == mClass && other.mInstName.equals(mInstName)
&& other.mObj == mObj);
}
}
protected void waitUntilReady() {
synchronized (mLock) {
if (!mReady) {
try {
mLock.wait(MAX_INIT_WAIT_MS);
} catch (InterruptedException ie) {
}
if (!mReady) {
fail("Telephony tests failed to initialize");
}
}
}
}
protected void setReady(boolean ready) {
synchronized (mLock) {
mReady = ready;
mLock.notifyAll();
}
}
protected synchronized void replaceInstance(final Class c, final String instanceName,
final Object obj, final Object newValue)
throws Exception {
Field field = c.getDeclaredField(instanceName);
field.setAccessible(true);
InstanceKey key = new InstanceKey(c, instanceName, obj);
if (!mOldInstances.containsKey(key)) {
mOldInstances.put(key, field.get(obj));
mInstanceKeys.add(key);
}
field.set(obj, newValue);
}
protected synchronized void restoreInstance(final Class c, final String instanceName,
final Object obj) throws Exception {
InstanceKey key = new InstanceKey(c, instanceName, obj);
if (mOldInstances.containsKey(key)) {
Field field = c.getDeclaredField(instanceName);
field.setAccessible(true);
field.set(obj, mOldInstances.get(key));
mOldInstances.remove(key);
mInstanceKeys.remove(key);
}
}
protected synchronized void restoreInstances() throws Exception {
Iterator<InstanceKey> it = mInstanceKeys.descendingIterator();
while (it.hasNext()) {
InstanceKey key = it.next();
Field field = key.mClass.getDeclaredField(key.mInstName);
field.setAccessible(true);
field.set(key.mObj, mOldInstances.get(key));
}
mInstanceKeys.clear();
mOldInstances.clear();
}
// TODO: Unit tests that do not extend TelephonyTest or ImsTestBase should enable strict mode
// by calling this method.
public static void enableStrictMode() {
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
.detectLeakedClosableObjects()
.detectIncorrectContextUse()
.detectLeakedRegistrationObjects()
.detectUnsafeIntentLaunch()
.detectActivityLeaks()
.penaltyLog()
.penaltyDeath()
.build());
}
protected void setUp(String tag) throws Exception {
TAG = tag;
enableStrictMode();
mPhone = Mockito.mock(GsmCdmaPhone.class);
mImsPhone = Mockito.mock(ImsPhone.class);
mSST = Mockito.mock(ServiceStateTracker.class);
mEmergencyNumberTracker = Mockito.mock(EmergencyNumberTracker.class);
mCT = Mockito.mock(GsmCdmaCallTracker.class);
mImsCT = Mockito.mock(ImsPhoneCallTracker.class);
mUiccController = Mockito.mock(UiccController.class);
mUiccProfile = Mockito.mock(UiccProfile.class);
mCallManager = Mockito.mock(CallManager.class);
mNotifier = Mockito.mock(PhoneNotifier.class);
mTelephonyComponentFactory = Mockito.mock(TelephonyComponentFactory.class);
mCdmaSSM = Mockito.mock(CdmaSubscriptionSourceManager.class);
mRegistrantList = Mockito.mock(RegistrantList.class);
mIccPhoneBookIntManager = Mockito.mock(IccPhoneBookInterfaceManager.class);
mImsManager = Mockito.mock(ImsManager.class);
mDcTracker = Mockito.mock(DcTracker.class);
mDataNetworkController = Mockito.mock(DataNetworkController.class);
mDataRetryManager = Mockito.mock(DataRetryManager.class);
mDataSettingsManager = Mockito.mock(DataSettingsManager.class);
mDataConfigManager = Mockito.mock(DataConfigManager.class);
mDataProfileManager = Mockito.mock(DataProfileManager.class);
mDisplayInfoController = Mockito.mock(DisplayInfoController.class);
mGsmCdmaCall = Mockito.mock(GsmCdmaCall.class);
mImsCall = Mockito.mock(ImsCall.class);
mImsEcbm = Mockito.mock(ImsEcbm.class);
mSubscriptionController = Mockito.mock(SubscriptionController.class);
mServiceState = Mockito.mock(ServiceState.class);
mMockPackageManager = Mockito.mock(IPackageManager.Stub.class);
mMockLegacyPermissionManager = Mockito.mock(LegacyPermissionManagerService.class);
mSimulatedCommandsVerifier = Mockito.mock(SimulatedCommandsVerifier.class);
mInboundSmsHandler = Mockito.mock(InboundSmsHandler.class);
mWspTypeDecoder = Mockito.mock(WspTypeDecoder.class);
mUiccCardApplication3gpp = Mockito.mock(UiccCardApplication.class);
mUiccCardApplication3gpp2 = Mockito.mock(UiccCardApplication.class);
mUiccCardApplicationIms = Mockito.mock(UiccCardApplication.class);
mSimRecords = Mockito.mock(SIMRecords.class);
mRuimRecords = Mockito.mock(RuimRecords.class);
mIsimUiccRecords = Mockito.mock(IsimUiccRecords.class);
mProxyController = Mockito.mock(ProxyController.class);
mIActivityManagerSingleton = Mockito.mock(Singleton.class);
mIActivityManager = Mockito.mock(IActivityManager.class);
mIIntentSender = Mockito.mock(IIntentSender.class);
mIBinder = Mockito.mock(IBinder.class);
mSmsStorageMonitor = Mockito.mock(SmsStorageMonitor.class);
mSmsUsageMonitor = Mockito.mock(SmsUsageMonitor.class);
mPackageInfo = Mockito.mock(PackageInfo.class);
mApplicationInfo = Mockito.mock(ApplicationInfo.class);
mEriManager = Mockito.mock(EriManager.class);
mConnMetLoggerBinder = Mockito.mock(IBinder.class);
mCarrierSignalAgent = Mockito.mock(CarrierSignalAgent.class);
mCarrierActionAgent = Mockito.mock(CarrierActionAgent.class);
mImsExternalCallTracker = Mockito.mock(ImsExternalCallTracker.class);
mAppSmsManager = Mockito.mock(AppSmsManager.class);
mIccSmsInterfaceManager = Mockito.mock(IccSmsInterfaceManager.class);
mSmsDispatchersController = Mockito.mock(SmsDispatchersController.class);
mDeviceStateMonitor = Mockito.mock(DeviceStateMonitor.class);
mAccessNetworksManager = Mockito.mock(AccessNetworksManager.class);
mIntentBroadcaster = Mockito.mock(IntentBroadcaster.class);
mNitzStateMachine = Mockito.mock(NitzStateMachine.class);
mMockRadioConfig = Mockito.mock(RadioConfig.class);
mSubInfoRecordUpdater = Mockito.mock(SubscriptionInfoUpdater.class);
mLocaleTracker = Mockito.mock(LocaleTracker.class);
mRestrictedState = Mockito.mock(RestrictedState.class);
mDataEnabledSettings = Mockito.mock(DataEnabledSettings.class);
mDataEnabledOverride = Mockito.mock(DataEnabledOverride.class);
mPhoneConfigurationManager = Mockito.mock(PhoneConfigurationManager.class);
mCellularNetworkValidator = Mockito.mock(CellularNetworkValidator.class);
mUiccCard = Mockito.mock(UiccCard.class);
mUiccPort = Mockito.mock(UiccPort.class);
mMultiSimSettingController = Mockito.mock(MultiSimSettingController.class);
mIccCard = Mockito.mock(IccCard.class);
mStatsManager = Mockito.mock(NetworkStatsManager.class);
mCarrierPrivilegesTracker = Mockito.mock(CarrierPrivilegesTracker.class);
mVoiceCallSessionStats = Mockito.mock(VoiceCallSessionStats.class);
mPersistAtomsStorage = Mockito.mock(PersistAtomsStorage.class);
mMetricsCollector = Mockito.mock(MetricsCollector.class);
mSmsStats = Mockito.mock(SmsStats.class);
mDataThrottler = Mockito.mock(DataThrottler.class);
mSignalStrength = Mockito.mock(SignalStrength.class);
mWifiManager = Mockito.mock(WifiManager.class);
mWifiInfo = Mockito.mock(WifiInfo.class);
mImsStats = Mockito.mock(ImsStats.class);
mLinkBandwidthEstimator = Mockito.mock(LinkBandwidthEstimator.class);
mPinStorage = Mockito.mock(PinStorage.class);
mLocationManager = Mockito.mock(LocationManager.class);
mCellIdentity = Mockito.mock(CellIdentity.class);
mCellLocation = Mockito.mock(CellLocation.class);
mMockedWwanDataServiceManager = Mockito.mock(DataServiceManager.class);
mMockedWlanDataServiceManager = Mockito.mock(DataServiceManager.class);
TelephonyManager.disableServiceHandleCaching();
SubscriptionController.disableCaching();
// For testing do not allow Log.WTF as it can cause test process to crash
Log.setWtfHandler((tagString, what, system) -> Log.d(TAG, "WTF captured, ignoring. Tag: "
+ tagString + ", exception: " + what));
mPhones = new Phone[] {mPhone};
mImsCallProfile = new ImsCallProfile();
mImsCallProfile.setCallerNumberVerificationStatus(
ImsCallProfile.VERIFICATION_STATUS_PASSED);
mSimulatedCommands = new SimulatedCommands();
mContextFixture = new ContextFixture();
mContext = mContextFixture.getTestDouble();
mFakeBlockedNumberContentProvider = new FakeBlockedNumberContentProvider();
((MockContentResolver)mContext.getContentResolver()).addProvider(
BlockedNumberContract.AUTHORITY, mFakeBlockedNumberContentProvider);
((MockContentResolver) mContext.getContentResolver()).addProvider(
Settings.AUTHORITY, mContentProvider);
((MockContentResolver) mContext.getContentResolver()).addProvider(
Telephony.ServiceStateTable.AUTHORITY, mContentProvider);
replaceContentProvider(mContentProvider);
Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0);
mPhone.mCi = mSimulatedCommands;
mCT.mCi = mSimulatedCommands;
doReturn(mUiccCard).when(mPhone).getUiccCard();
doReturn(mUiccPort).when(mPhone).getUiccPort();
doReturn(mUiccProfile).when(mUiccPort).getUiccProfile();
mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
mTelephonyRegistryManager = (TelephonyRegistryManager) mContext.getSystemService(
Context.TELEPHONY_REGISTRY_SERVICE);
mSubscriptionManager = (SubscriptionManager) mContext.getSystemService(
Context.TELEPHONY_SUBSCRIPTION_SERVICE);
mEuiccManager = (EuiccManager) mContext.getSystemService(Context.EUICC_SERVICE);
mConnectivityManager = (ConnectivityManager)
mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
mPackageManager = mContext.getPackageManager();
mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
mCarrierConfigManager =
(CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
mVcnManager = mContext.getSystemService(VcnManager.class);
mNetworkPolicyManager = mContext.getSystemService(NetworkPolicyManager.class);
mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
//mTelephonyComponentFactory
doReturn(mTelephonyComponentFactory).when(mTelephonyComponentFactory).inject(anyString());
doReturn(mSST).when(mTelephonyComponentFactory)
.makeServiceStateTracker(nullable(GsmCdmaPhone.class),
nullable(CommandsInterface.class));
doReturn(mEmergencyNumberTracker).when(mTelephonyComponentFactory)
.makeEmergencyNumberTracker(nullable(Phone.class),
nullable(CommandsInterface.class));
doReturn(getTestEmergencyNumber()).when(mEmergencyNumberTracker)
.getEmergencyNumber(any());
doReturn(mUiccProfile).when(mTelephonyComponentFactory)
.makeUiccProfile(nullable(Context.class), nullable(CommandsInterface.class),
nullable(IccCardStatus.class), anyInt(), nullable(UiccCard.class),
nullable(Object.class));
doReturn(mCT).when(mTelephonyComponentFactory)
.makeGsmCdmaCallTracker(nullable(GsmCdmaPhone.class));
doReturn(mIccPhoneBookIntManager).when(mTelephonyComponentFactory)
.makeIccPhoneBookInterfaceManager(nullable(Phone.class));
doReturn(mDcTracker).when(mTelephonyComponentFactory)
.makeDcTracker(nullable(Phone.class), anyInt());
doReturn(mDisplayInfoController).when(mTelephonyComponentFactory)
.makeDisplayInfoController(nullable(Phone.class));
doReturn(mWspTypeDecoder).when(mTelephonyComponentFactory)
.makeWspTypeDecoder(nullable(byte[].class));
doReturn(mImsCT).when(mTelephonyComponentFactory)
.makeImsPhoneCallTracker(nullable(ImsPhone.class));
doReturn(mCdmaSSM).when(mTelephonyComponentFactory)
.getCdmaSubscriptionSourceManagerInstance(nullable(Context.class),
nullable(CommandsInterface.class), nullable(Handler.class),
anyInt(), nullable(Object.class));
doReturn(mImsExternalCallTracker).when(mTelephonyComponentFactory)
.makeImsExternalCallTracker(nullable(ImsPhone.class));
doReturn(mAppSmsManager).when(mTelephonyComponentFactory)
.makeAppSmsManager(nullable(Context.class));
doReturn(mCarrierSignalAgent).when(mTelephonyComponentFactory)
.makeCarrierSignalAgent(nullable(Phone.class));
doReturn(mCarrierActionAgent).when(mTelephonyComponentFactory)
.makeCarrierActionAgent(nullable(Phone.class));
doReturn(mDeviceStateMonitor).when(mTelephonyComponentFactory)
.makeDeviceStateMonitor(nullable(Phone.class));
doReturn(mAccessNetworksManager).when(mTelephonyComponentFactory)
.makeAccessNetworksManager(nullable(Phone.class), any(Looper.class));
doReturn(mNitzStateMachine).when(mTelephonyComponentFactory)
.makeNitzStateMachine(nullable(GsmCdmaPhone.class));
doReturn(mLocaleTracker).when(mTelephonyComponentFactory)
.makeLocaleTracker(nullable(Phone.class), nullable(NitzStateMachine.class),
nullable(Looper.class));
doReturn(mDataEnabledSettings).when(mTelephonyComponentFactory)
.makeDataEnabledSettings(nullable(Phone.class));
doReturn(mEriManager).when(mTelephonyComponentFactory)
.makeEriManager(nullable(Phone.class), anyInt());
doReturn(mLinkBandwidthEstimator).when(mTelephonyComponentFactory)
.makeLinkBandwidthEstimator(nullable(Phone.class));
doReturn(mDataProfileManager).when(mTelephonyComponentFactory)
.makeDataProfileManager(any(Phone.class), any(DataNetworkController.class),
any(DataServiceManager.class), any(Looper.class),
any(DataProfileManager.DataProfileManagerCallback.class));
//mPhone
doReturn(mContext).when(mPhone).getContext();
doReturn(mContext).when(mImsPhone).getContext();
doReturn(true).when(mPhone).getUnitTestMode();
doReturn(mUiccProfile).when(mPhone).getIccCard();
doReturn(mServiceState).when(mPhone).getServiceState();
doReturn(mServiceState).when(mImsPhone).getServiceState();
doReturn(mPhone).when(mImsPhone).getDefaultPhone();
doReturn(true).when(mPhone).isPhoneTypeGsm();
doReturn(PhoneConstants.PHONE_TYPE_GSM).when(mPhone).getPhoneType();
doReturn(mCT).when(mPhone).getCallTracker();
doReturn(mSST).when(mPhone).getServiceStateTracker();
doReturn(mDeviceStateMonitor).when(mPhone).getDeviceStateMonitor();
doReturn(mDisplayInfoController).when(mPhone).getDisplayInfoController();
doReturn(mEmergencyNumberTracker).when(mPhone).getEmergencyNumberTracker();
doReturn(mCarrierSignalAgent).when(mPhone).getCarrierSignalAgent();
doReturn(mCarrierActionAgent).when(mPhone).getCarrierActionAgent();
doReturn(mAppSmsManager).when(mPhone).getAppSmsManager();
doReturn(mIccSmsInterfaceManager).when(mPhone).getIccSmsInterfaceManager();
doReturn(mAccessNetworksManager).when(mPhone).getAccessNetworksManager();
doReturn(mDataEnabledSettings).when(mPhone).getDataEnabledSettings();
doReturn(mDcTracker).when(mPhone).getDcTracker(anyInt());
doReturn(mDataSettingsManager).when(mDataNetworkController).getDataSettingsManager();
doReturn(mDataNetworkController).when(mPhone).getDataNetworkController();
doReturn(mDataSettingsManager).when(mPhone).getDataSettingsManager();
doReturn(mCarrierPrivilegesTracker).when(mPhone).getCarrierPrivilegesTracker();
doReturn(mSignalStrength).when(mPhone).getSignalStrength();
doReturn(mVoiceCallSessionStats).when(mPhone).getVoiceCallSessionStats();
doReturn(mVoiceCallSessionStats).when(mImsPhone).getVoiceCallSessionStats();
doReturn(mSmsStats).when(mPhone).getSmsStats();
doReturn(mImsStats).when(mImsPhone).getImsStats();
mIccSmsInterfaceManager.mDispatchersController = mSmsDispatchersController;
doReturn(mLinkBandwidthEstimator).when(mPhone).getLinkBandwidthEstimator();
doReturn(mCellIdentity).when(mPhone).getCurrentCellIdentity();
doReturn(mCellLocation).when(mCellIdentity).asCellLocation();
doReturn(mDataConfigManager).when(mDataNetworkController).getDataConfigManager();
doReturn(mDataProfileManager).when(mDataNetworkController).getDataProfileManager();
doReturn(mDataRetryManager).when(mDataNetworkController).getDataRetryManager();
doReturn(mCarrierPrivilegesTracker).when(mPhone).getCarrierPrivilegesTracker();
doReturn(true).when(mPhone).isUsingNewDataStack();
//mUiccController
doReturn(mUiccCardApplication3gpp).when(mUiccController).getUiccCardApplication(anyInt(),
eq(UiccController.APP_FAM_3GPP));
doReturn(mUiccCardApplication3gpp2).when(mUiccController).getUiccCardApplication(anyInt(),
eq(UiccController.APP_FAM_3GPP2));
doReturn(mUiccCardApplicationIms).when(mUiccController).getUiccCardApplication(anyInt(),
eq(UiccController.APP_FAM_IMS));
doReturn(mUiccCard).when(mUiccController).getUiccCard(anyInt());
doReturn(mUiccPort).when(mUiccController).getUiccPort(anyInt());
doAnswer(new Answer<IccRecords>() {
public IccRecords answer(InvocationOnMock invocation) {
switch ((Integer) invocation.getArguments()[1]) {
case UiccController.APP_FAM_3GPP:
return mSimRecords;
case UiccController.APP_FAM_3GPP2:
return mRuimRecords;
case UiccController.APP_FAM_IMS:
return mIsimUiccRecords;
default:
logd("Unrecognized family " + invocation.getArguments()[1]);
return null;
}
}
}).when(mUiccController).getIccRecords(anyInt(), anyInt());
doReturn(new UiccSlot[] {}).when(mUiccController).getUiccSlots();
doReturn(mPinStorage).when(mUiccController).getPinStorage();
//UiccCardApplication
doReturn(mSimRecords).when(mUiccCardApplication3gpp).getIccRecords();
doReturn(mRuimRecords).when(mUiccCardApplication3gpp2).getIccRecords();
doReturn(mIsimUiccRecords).when(mUiccCardApplicationIms).getIccRecords();
//mUiccProfile
doReturn(mSimRecords).when(mUiccProfile).getIccRecords();
doAnswer(new Answer<IccRecords>() {
public IccRecords answer(InvocationOnMock invocation) {
return (mPhone.isPhoneTypeGsm()) ? mSimRecords : mRuimRecords;
}
}).when(mUiccProfile).getIccRecords();
//mUiccProfile
doReturn(mUiccCardApplication3gpp).when(mUiccProfile).getApplication(
eq(UiccController.APP_FAM_3GPP));
doReturn(mUiccCardApplication3gpp2).when(mUiccProfile).getApplication(
eq(UiccController.APP_FAM_3GPP2));
doReturn(mUiccCardApplicationIms).when(mUiccProfile).getApplication(
eq(UiccController.APP_FAM_IMS));
//SMS
doReturn(true).when(mSmsStorageMonitor).isStorageAvailable();
doReturn(true).when(mSmsUsageMonitor).check(nullable(String.class), anyInt());
doReturn(true).when(mTelephonyManager).getSmsReceiveCapableForPhone(anyInt(), anyBoolean());
doReturn(true).when(mTelephonyManager).getSmsSendCapableForPhone(
anyInt(), anyBoolean());
//Misc
doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS).when(mServiceState).
getRilDataRadioTechnology();
doReturn(mPhone).when(mCT).getPhone();
doReturn(mImsEcbm).when(mImsManager).getEcbmInterface();
doReturn(mPhone).when(mInboundSmsHandler).getPhone();
doReturn(mImsCallProfile).when(mImsCall).getCallProfile();
doReturn(mIBinder).when(mIIntentSender).asBinder();
doReturn(mIIntentSender).when(mIActivityManager).getIntentSenderWithFeature(anyInt(),
nullable(String.class), nullable(String.class), nullable(IBinder.class),
nullable(String.class), anyInt(), nullable(Intent[].class),
nullable(String[].class), anyInt(), nullable(Bundle.class), anyInt());
doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(anyInt());
doReturn(true).when(mTelephonyManager).isDataCapable();
doReturn(TelephonyManager.PHONE_TYPE_GSM).when(mTelephonyManager).getPhoneType();
doReturn(mServiceState).when(mSST).getServiceState();
mSST.mSS = mServiceState;
mSST.mRestrictedState = mRestrictedState;
mServiceManagerMockedServices.put("connectivity_metrics_logger", mConnMetLoggerBinder);
mServiceManagerMockedServices.put("package", mMockPackageManager);
mServiceManagerMockedServices.put("legacy_permission", mMockLegacyPermissionManager);
logd("mMockLegacyPermissionManager replaced");
doReturn(new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
AccessNetworkConstants.TRANSPORT_TYPE_WLAN})
.when(mAccessNetworksManager).getAvailableTransports();
doReturn(new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
AccessNetworkConstants.TRANSPORT_TYPE_WLAN})
.when(mAccessNetworksManager).getAvailableTransports();
doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mAccessNetworksManager)
.getCurrentTransport(anyInt());
doReturn(true).when(mDataEnabledSettings).isDataEnabled();
doReturn(true).when(mDataEnabledSettings).isDataEnabled(anyInt());
doReturn(true).when(mDataEnabledSettings).isInternalDataEnabled();
doReturn(true).when(mDataSettingsManager).isDataEnabled();
doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
anyInt(), anyInt());
doReturn(new HalVersion(1, 4)).when(mPhone).getHalVersion();
doReturn(2).when(mSignalStrength).getLevel();
// WiFi
doReturn(mWifiInfo).when(mWifiManager).getConnectionInfo();
doReturn(2).when(mWifiManager).calculateSignalLevel(anyInt());
doReturn(4).when(mWifiManager).getMaxSignalLevel();
doAnswer(invocation -> {
NetworkCapabilities nc = invocation.getArgument(0);
return new VcnNetworkPolicyResult(
false /* isTearDownRequested */, nc);
}).when(mVcnManager).applyVcnNetworkPolicy(any(), any());
//SIM
doReturn(1).when(mTelephonyManager).getSimCount();
doReturn(1).when(mTelephonyManager).getPhoneCount();
doReturn(1).when(mTelephonyManager).getActiveModemCount();
// Have getMaxPhoneCount always return the same value with getPhoneCount by default.
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.
ContentResolver resolver = mContext.getContentResolver();
Settings.Global.putInt(resolver, Settings.Global.MOBILE_DATA, 1);
Settings.Global.putInt(resolver, Settings.Global.DEVICE_PROVISIONED, 1);
Settings.Global.putInt(resolver,
Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED, 1);
doReturn(mDataThrottler).when(mDcTracker).getDataThrottler();
doReturn(-1L).when(mDataThrottler).getRetryTime(anyInt());
doReturn(90).when(mDataConfigManager).getNetworkCapabilityPriority(
eq(NetworkCapabilities.NET_CAPABILITY_EIMS));
doReturn(80).when(mDataConfigManager).getNetworkCapabilityPriority(
eq(NetworkCapabilities.NET_CAPABILITY_SUPL));
doReturn(70).when(mDataConfigManager).getNetworkCapabilityPriority(
eq(NetworkCapabilities.NET_CAPABILITY_MMS));
doReturn(70).when(mDataConfigManager).getNetworkCapabilityPriority(
eq(NetworkCapabilities.NET_CAPABILITY_XCAP));
doReturn(50).when(mDataConfigManager).getNetworkCapabilityPriority(
eq(NetworkCapabilities.NET_CAPABILITY_CBS));
doReturn(50).when(mDataConfigManager).getNetworkCapabilityPriority(
eq(NetworkCapabilities.NET_CAPABILITY_MCX));
doReturn(50).when(mDataConfigManager).getNetworkCapabilityPriority(
eq(NetworkCapabilities.NET_CAPABILITY_FOTA));
doReturn(40).when(mDataConfigManager).getNetworkCapabilityPriority(
eq(NetworkCapabilities.NET_CAPABILITY_IMS));
doReturn(30).when(mDataConfigManager).getNetworkCapabilityPriority(
eq(NetworkCapabilities.NET_CAPABILITY_DUN));
doReturn(20).when(mDataConfigManager).getNetworkCapabilityPriority(
eq(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
doReturn(20).when(mDataConfigManager).getNetworkCapabilityPriority(
eq(NetworkCapabilities.NET_CAPABILITY_INTERNET));
// CellularNetworkValidator
doReturn(SubscriptionManager.INVALID_PHONE_INDEX)
.when(mCellularNetworkValidator).getSubIdInValidation();
doReturn(true).when(mCellularNetworkValidator).isValidationFeatureSupported();
// Metrics
doReturn(null).when(mContext).getFileStreamPath(anyString());
doReturn(mPersistAtomsStorage).when(mMetricsCollector).getAtomsStorage();
doReturn(mWifiManager).when(mContext).getSystemService(eq(Context.WIFI_SERVICE));
//Use reflection to mock singletons
replaceInstance(CallManager.class, "INSTANCE", null, mCallManager);
replaceInstance(TelephonyComponentFactory.class, "sInstance", null,
mTelephonyComponentFactory);
replaceInstance(UiccController.class, "mInstance", null, mUiccController);
replaceInstance(CdmaSubscriptionSourceManager.class, "sInstance", null, mCdmaSSM);
replaceInstance(SubscriptionController.class, "sInstance", null, mSubscriptionController);
replaceInstance(ProxyController.class, "sProxyController", null, mProxyController);
replaceInstance(ActivityManager.class, "IActivityManagerSingleton", null,
mIActivityManagerSingleton);
replaceInstance(CdmaSubscriptionSourceManager.class,
"mCdmaSubscriptionSourceChangedRegistrants", mCdmaSSM, mRegistrantList);
replaceInstance(SimulatedCommandsVerifier.class, "sInstance", null,
mSimulatedCommandsVerifier);
replaceInstance(Singleton.class, "mInstance", mIActivityManagerSingleton,
mIActivityManager);
replaceInstance(ServiceManager.class, "sCache", null, mServiceManagerMockedServices);
replaceInstance(IntentBroadcaster.class, "sIntentBroadcaster", null, mIntentBroadcaster);
replaceInstance(TelephonyManager.class, "sInstance", null,
mContext.getSystemService(Context.TELEPHONY_SERVICE));
replaceInstance(TelephonyManager.class, "sServiceHandleCacheEnabled", null, false);
replaceInstance(PhoneFactory.class, "sMadeDefaults", null, true);
replaceInstance(PhoneFactory.class, "sPhone", null, mPhone);
replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
replaceInstance(PhoneFactory.class, "sSubInfoRecordUpdater", null, mSubInfoRecordUpdater);
replaceInstance(RadioConfig.class, "sRadioConfig", null, mMockRadioConfig);
replaceInstance(PhoneConfigurationManager.class, "sInstance", null,
mPhoneConfigurationManager);
replaceInstance(CellularNetworkValidator.class, "sInstance", null,
mCellularNetworkValidator);
replaceInstance(MultiSimSettingController.class, "sInstance", null,
mMultiSimSettingController);
replaceInstance(SubscriptionInfoUpdater.class, "sIsSubInfoInitialized", null, true);
replaceInstance(PhoneFactory.class, "sCommandsInterfaces", null,
new CommandsInterface[] {mSimulatedCommands});
replaceInstance(PhoneFactory.class, "sMetricsCollector", null, mMetricsCollector);
assertNotNull("Failed to set up SubscriptionController singleton",
SubscriptionController.getInstance());
setReady(false);
// create default TestableLooper for test and add to list of monitored loopers
mTestableLooper = TestableLooper.get(TelephonyTest.this);
if (mTestableLooper != null) {
monitorTestableLooper(mTestableLooper);
}
}
protected void tearDown() throws Exception {
// Clear all remaining messages
if (!mTestableLoopers.isEmpty()) {
for (TestableLooper looper : mTestableLoopers) {
looper.getLooper().quit();
}
}
// Ensure there are no references to handlers between tests.
PhoneConfigurationManager.unregisterAllMultiSimConfigChangeRegistrants();
// unmonitor TestableLooper for TelephonyTest class
if (mTestableLooper != null) {
unmonitorTestableLooper(mTestableLooper);
}
// destroy all newly created TestableLoopers so they can be reused
for (TestableLooper looper : mTestableLoopers) {
looper.destroy();
}
TestableLooper.remove(TelephonyTest.this);
mSimulatedCommands.dispose();
SharedPreferences sharedPreferences = mContext.getSharedPreferences((String) null, 0);
sharedPreferences.edit().clear().commit();
restoreInstances();
TelephonyManager.enableServiceHandleCaching();
SubscriptionController.enableCaching();
mNetworkRegistrationInfo = null;
mActivityManager = null;
mImsCallProfile = null;
mTelephonyManager = null;
mTelephonyRegistryManager = null;
mSubscriptionManager = null;
mEuiccManager = null;
mPackageManager = null;
mConnectivityManager = null;
mAppOpsManager = null;
mCarrierConfigManager = null;
mUserManager = null;
mKeyguardManager = null;
mVcnManager = null;
mNetworkPolicyManager = null;
mSimulatedCommands = null;
mContextFixture = null;
mContext = null;
mFakeBlockedNumberContentProvider = null;
mLock = null;
mServiceManagerMockedServices.clear();
mServiceManagerMockedServices = null;
mPhone = null;
mTestableLoopers.clear();
mTestableLoopers = null;
mTestableLooper = null;
}
protected static void logd(String s) {
Log.d(TAG, s);
}
public static class FakeBlockedNumberContentProvider extends MockContentProvider {
public Set<String> mBlockedNumbers = new HashSet<>();
public int mNumEmergencyContactNotifications = 0;
@Override
public Bundle call(String method, String arg, Bundle extras) {
switch (method) {
case BlockedNumberContract.SystemContract.METHOD_SHOULD_SYSTEM_BLOCK_NUMBER:
Bundle bundle = new Bundle();
int blockStatus = mBlockedNumbers.contains(arg)
? BlockedNumberContract.STATUS_BLOCKED_IN_LIST
: BlockedNumberContract.STATUS_NOT_BLOCKED;
bundle.putInt(BlockedNumberContract.RES_BLOCK_STATUS, blockStatus);
return bundle;
case BlockedNumberContract.SystemContract.METHOD_NOTIFY_EMERGENCY_CONTACT:
mNumEmergencyContactNotifications++;
return new Bundle();
default:
fail("Method not expected: " + method);
}
return null;
}
}
public static class FakeSettingsConfigProvider extends MockContentProvider {
private static final String PROPERTY_DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_DISABLED =
DeviceConfig.NAMESPACE_PRIVACY + "/"
+ "device_identifier_access_restrictions_disabled";
@Override
public Bundle call(String method, String arg, Bundle extras) {
switch (method) {
case Settings.CALL_METHOD_GET_CONFIG: {
switch (arg) {
case PROPERTY_DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_DISABLED: {
Bundle bundle = new Bundle();
bundle.putString(
PROPERTY_DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_DISABLED,
"0");
return bundle;
}
default: {
fail("arg not expected: " + arg);
}
}
break;
}
default:
fail("Method not expected: " + method);
}
return null;
}
}
protected void setupMockPackagePermissionChecks() throws Exception {
doReturn(new String[]{TAG}).when(mPackageManager).getPackagesForUid(anyInt());
doReturn(mPackageInfo).when(mPackageManager).getPackageInfo(eq(TAG), anyInt());
}
protected void setupMocksForTelephonyPermissions() throws Exception {
setupMocksForTelephonyPermissions(Build.VERSION_CODES.Q);
}
protected void setupMocksForTelephonyPermissions(int targetSdkVersion)
throws Exception {
// If the calling package does not meet the new requirements for device identifier access
// TelephonyPermissions will query the PackageManager for the ApplicationInfo of the package
// to determine the target SDK. For apps targeting Q a SecurityException is thrown
// regardless of if the package satisfies the previous requirements for device ID access.
// Any tests that query for SubscriptionInfo objects will trigger a phone number access
// check that will first query the ApplicationInfo as apps targeting R+ can no longer
// access the phone number with the READ_PHONE_STATE permission and instead must meet one of
// the other requirements. This ApplicationInfo is generalized to any package name since
// some tests will simulate invocation from other packages.
mApplicationInfo.targetSdkVersion = targetSdkVersion;
doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfoAsUser(anyString(),
anyInt(), any());
// TelephonyPermissions uses a SystemAPI to check if the calling package meets any of the
// generic requirements for device identifier access (currently READ_PRIVILEGED_PHONE_STATE,
// appop, and device / profile owner checks). This sets up the PermissionManager to return
// that access requirements are met.
setIdentifierAccess(true);
LegacyPermissionManager legacyPermissionManager =
new LegacyPermissionManager(mMockLegacyPermissionManager);
doReturn(legacyPermissionManager).when(mContext)
.getSystemService(Context.LEGACY_PERMISSION_SERVICE);
// Also make sure all appop checks fails, to not interfere tests. Tests should explicitly
// mock AppOpManager to return allowed/default mode. Note by default a mock returns 0 which
// is MODE_ALLOWED, hence this setup is necessary.
doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager).noteOpNoThrow(
/* op= */ anyString(), /* uid= */ anyInt(),
/* packageName= */ nullable(String.class),
/* attributionTag= */ nullable(String.class),
/* message= */ nullable(String.class));
// TelephonyPermissions queries DeviceConfig to determine if the identifier access
// restrictions should be enabled; this results in a NPE when DeviceConfig uses
// Activity.currentActivity.getContentResolver as the resolver for Settings.Config.getString
// since the IContentProvider in the NameValueCache's provider holder is null.
replaceContentProvider(new FakeSettingsConfigProvider());
}
private void replaceContentProvider(ContentProvider contentProvider) throws Exception {
Class c = Class.forName("android.provider.Settings$Config");
Field field = c.getDeclaredField("sNameValueCache");
field.setAccessible(true);
Object cache = field.get(null);
c = Class.forName("android.provider.Settings$NameValueCache");
field = c.getDeclaredField("mProviderHolder");
field.setAccessible(true);
Object providerHolder = field.get(cache);
field = MockContentProvider.class.getDeclaredField("mIContentProvider");
field.setAccessible(true);
Object iContentProvider = field.get(contentProvider);
replaceInstance(Class.forName("android.provider.Settings$ContentProviderHolder"),
"mContentProvider", providerHolder, iContentProvider);
}
protected void setIdentifierAccess(boolean hasAccess) {
doReturn(hasAccess ? PackageManager.PERMISSION_GRANTED
: PackageManager.PERMISSION_DENIED).when(mMockLegacyPermissionManager)
.checkDeviceIdentifierAccess(any(), any(), any(), anyInt(), anyInt());
}
protected void setPhoneNumberAccess(int value) {
doReturn(value).when(mMockLegacyPermissionManager).checkPhoneNumberAccess(any(), any(),
any(), anyInt(), anyInt());
}
protected void setCarrierPrivileges(boolean hasCarrierPrivileges) {
doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(anyInt());
doReturn(hasCarrierPrivileges ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
: TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS).when(
mTelephonyManager).getCarrierPrivilegeStatus(anyInt());
}
protected void setCarrierPrivilegesForSubId(boolean hasCarrierPrivileges, int subId) {
TelephonyManager mockTelephonyManager = Mockito.mock(TelephonyManager.class);
doReturn(mockTelephonyManager).when(mTelephonyManager).createForSubscriptionId(subId);
doReturn(hasCarrierPrivileges ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
: TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS).when(
mockTelephonyManager).getCarrierPrivilegeStatus(anyInt());
}
protected final void waitForDelayedHandlerAction(Handler h, long delayMillis,
long timeoutMillis) {
final CountDownLatch lock = new CountDownLatch(1);
h.postDelayed(lock::countDown, delayMillis);
while (lock.getCount() > 0) {
try {
lock.await(delayMillis + timeoutMillis, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// do nothing
}
}
}
protected final void waitForHandlerAction(Handler h, long timeoutMillis) {
final CountDownLatch lock = new CountDownLatch(1);
h.post(lock::countDown);
while (lock.getCount() > 0) {
try {
lock.await(timeoutMillis, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// do nothing
}
}
}
/**
* Wait for up to 1 second for the handler message queue to clear.
*/
protected final void waitForLastHandlerAction(Handler h) {
CountDownLatch lock = new CountDownLatch(1);
// Allow the handler to start work on stuff.
h.postDelayed(lock::countDown, 100);
int timeoutCount = 0;
while (timeoutCount < 5) {
try {
if (lock.await(200, TimeUnit.MILLISECONDS)) {
// no messages in queue, stop waiting.
if (!h.hasMessagesOrCallbacks()) break;
lock = new CountDownLatch(1);
// Delay to allow the handler thread to start work on stuff.
h.postDelayed(lock::countDown, 100);
}
} catch (InterruptedException e) {
// do nothing
}
timeoutCount++;
}
assertTrue("Handler was not empty before timeout elapsed", timeoutCount < 5);
}
protected final EmergencyNumber getTestEmergencyNumber() {
return SAMPLE_EMERGENCY_NUMBER;
}
public static Object invokeMethod(
Object instance, String methodName, Class<?>[] parameterClasses, Object[] parameters) {
try {
Method method = instance.getClass().getDeclaredMethod(methodName, parameterClasses);
method.setAccessible(true);
return method.invoke(instance, parameters);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
fail(instance.getClass() + " " + methodName + " " + e.getClass().getName());
}
return null;
}
/**
* Add a TestableLooper to the list of monitored loopers
* @param looper added if it doesn't already exist
*/
public void monitorTestableLooper(TestableLooper looper) {
if (!mTestableLoopers.contains(looper)) {
mTestableLoopers.add(looper);
}
}
/**
* Remove a TestableLooper from the list of monitored loopers
* @param looper removed if it does exist
*/
public void unmonitorTestableLooper(TestableLooper looper) {
if (mTestableLoopers.contains(looper)) {
mTestableLoopers.remove(looper);
}
}
/**
* Handle all messages that can be processed at the current time
* for all monitored TestableLoopers
*/
public void processAllMessages() {
if (mTestableLoopers.isEmpty()) {
fail("mTestableLoopers is empty. Please make sure to add @RunWithLooper annotation");
}
while (!areAllTestableLoopersIdle()) {
for (TestableLooper looper : mTestableLoopers) looper.processAllMessages();
}
}
/**
* @return The longest delay from all the message queues.
*/
private long getLongestDelay() {
long delay = 0;
for (TestableLooper looper : mTestableLoopers) {
MessageQueue queue = looper.getLooper().getQueue();
try {
Message msg = (Message) MESSAGE_QUEUE_FIELD.get(queue);
while (msg != null) {
delay = Math.max(msg.getWhen(), delay);
msg = (Message) MESSAGE_NEXT_FIELD.get(msg);
}
} catch (IllegalAccessException e) {
throw new RuntimeException("Access failed in TelephonyTest", e);
}
}
return delay;
}
/**
* @return {@code true} if there are any messages in the queue.
*/
private boolean messagesExist() {
for (TestableLooper looper : mTestableLoopers) {
MessageQueue queue = looper.getLooper().getQueue();
try {
Message msg = (Message) MESSAGE_QUEUE_FIELD.get(queue);
if (msg != null) return true;
} catch (IllegalAccessException e) {
throw new RuntimeException("Access failed in TelephonyTest", e);
}
}
return false;
}
/**
* Handle all messages including the delayed messages.
*/
public void processAllFutureMessages() {
while (messagesExist()) {
moveTimeForward(getLongestDelay());
processAllMessages();
}
}
/**
* Check if there are any messages to be processed in any monitored TestableLooper
* Delayed messages to be handled at a later time will be ignored
* @return true if there are no messages that can be handled at the current time
* across all monitored TestableLoopers
*/
private boolean areAllTestableLoopersIdle() {
for (TestableLooper looper : mTestableLoopers) {
if (!looper.getLooper().getQueue().isIdle()) return false;
}
return true;
}
/**
* Effectively moves time forward by reducing the time of all messages
* for all monitored TestableLoopers
* @param milliSeconds number of milliseconds to move time forward by
*/
public void moveTimeForward(long milliSeconds) {
for (TestableLooper looper : mTestableLoopers) {
MessageQueue queue = looper.getLooper().getQueue();
try {
Message msg = (Message) MESSAGE_QUEUE_FIELD.get(queue);
while (msg != null) {
long updatedWhen = msg.getWhen() - milliSeconds;
if (updatedWhen < 0) {
updatedWhen = 0;
}
MESSAGE_WHEN_FIELD.set(msg, updatedWhen);
msg = (Message) MESSAGE_NEXT_FIELD.get(msg);
}
} catch (IllegalAccessException e) {
throw new RuntimeException("Access failed in TelephonyTest", e);
}
}
}
}