1 /* 2 * Copyright (C) 2019 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.internal.telephony; 18 19 import static android.telephony.TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED; 20 import static android.telephony.TelephonyManager.EXTRA_ACTIVE_SIM_SUPPORTED_COUNT; 21 22 import static org.junit.Assert.assertEquals; 23 import static org.mockito.ArgumentMatchers.any; 24 import static org.mockito.ArgumentMatchers.anyInt; 25 import static org.mockito.ArgumentMatchers.anyLong; 26 import static org.mockito.ArgumentMatchers.eq; 27 import static org.mockito.Mockito.clearInvocations; 28 import static org.mockito.Mockito.doReturn; 29 import static org.mockito.Mockito.never; 30 import static org.mockito.Mockito.verify; 31 32 import android.content.Intent; 33 import android.os.AsyncResult; 34 import android.os.Handler; 35 import android.os.Message; 36 import android.telephony.PhoneCapability; 37 import android.test.suitebuilder.annotation.SmallTest; 38 import android.testing.AndroidTestingRunner; 39 import android.testing.TestableLooper; 40 41 import org.junit.After; 42 import org.junit.Before; 43 import org.junit.Test; 44 import org.junit.runner.RunWith; 45 import org.mockito.ArgumentCaptor; 46 import org.mockito.Mock; 47 48 @RunWith(AndroidTestingRunner.class) 49 @TestableLooper.RunWithLooper 50 public class PhoneConfigurationManagerTest extends TelephonyTest { 51 @Mock 52 Handler mHandler; 53 @Mock 54 CommandsInterface mMockCi; 55 @Mock 56 PhoneConfigurationManager.MockableInterface mMi; 57 58 private static final int EVENT_MULTI_SIM_CONFIG_CHANGED = 1; 59 PhoneConfigurationManager mPcm; 60 61 @Before setUp()62 public void setUp() throws Exception { 63 super.setUp(getClass().getSimpleName()); 64 mPhone.mCi = mMockCi; 65 mCT.mCi = mMockCi; 66 } 67 68 @After tearDown()69 public void tearDown() throws Exception { 70 // Restore system properties. 71 super.tearDown(); 72 } 73 setRebootRequiredForConfigSwitch(boolean rebootRequired)74 private void setRebootRequiredForConfigSwitch(boolean rebootRequired) { 75 doReturn(rebootRequired).when(mMi).isRebootRequiredForModemConfigChange(); 76 } 77 init(int numOfSim)78 private void init(int numOfSim) throws Exception { 79 doReturn(numOfSim).when(mTelephonyManager).getActiveModemCount(); 80 replaceInstance(PhoneConfigurationManager.class, "sInstance", null, null); 81 mPcm = PhoneConfigurationManager.init(mContext); 82 replaceInstance(PhoneConfigurationManager.class, "mMi", mPcm, mMi); 83 processAllMessages(); 84 } 85 86 /** 87 * Test that a single phone case results in our phone being active and the RIL called 88 */ 89 @Test 90 @SmallTest testGetPhoneCount()91 public void testGetPhoneCount() throws Exception { 92 init(1); 93 doReturn(1).when(mTelephonyManager).getActiveModemCount(); 94 assertEquals(1, mPcm.getPhoneCount()); 95 doReturn(2).when(mTelephonyManager).getActiveModemCount(); 96 assertEquals(2, mPcm.getPhoneCount()); 97 } 98 99 @Test 100 @SmallTest testEnablePhone()101 public void testEnablePhone() throws Exception { 102 init(1); 103 // Phone is null. No crash. 104 mPcm.enablePhone(null, true, null); 105 106 Message message = new Message(); 107 mPcm.enablePhone(mPhone, false, message); 108 verify(mMockCi).enableModem(eq(false), eq(message)); 109 } 110 111 @Test 112 @SmallTest testGetDsdsCapability()113 public void testGetDsdsCapability() throws Exception { 114 init(1); 115 assertEquals(PhoneCapability.DEFAULT_SSSS_CAPABILITY, mPcm.getStaticPhoneCapability()); 116 117 ArgumentCaptor<Message> captor = ArgumentCaptor.forClass(Message.class); 118 verify(mMockRadioConfig).getPhoneCapability(captor.capture()); 119 Message msg = captor.getValue(); 120 AsyncResult.forMessage(msg, PhoneCapability.DEFAULT_DSDS_CAPABILITY, null); 121 msg.sendToTarget(); 122 processAllMessages(); 123 124 // Not static capability should indicate DSDS capable. 125 assertEquals(PhoneCapability.DEFAULT_DSDS_CAPABILITY, mPcm.getStaticPhoneCapability()); 126 } 127 128 @Test 129 @SmallTest testSwitchMultiSimConfig_notDsdsCapable_shouldFail()130 public void testSwitchMultiSimConfig_notDsdsCapable_shouldFail() throws Exception { 131 init(1); 132 assertEquals(PhoneCapability.DEFAULT_SSSS_CAPABILITY, mPcm.getStaticPhoneCapability()); 133 134 // Try switching to dual SIM. Shouldn't work as we haven't indicated DSDS is supported. 135 mPcm.switchMultiSimConfig(2); 136 verify(mMockRadioConfig, never()).setModemsConfig(anyInt(), any()); 137 } 138 139 @Test 140 @SmallTest testSwitchMultiSimConfig_dsdsCapable_noRebootRequired()141 public void testSwitchMultiSimConfig_dsdsCapable_noRebootRequired() throws Exception { 142 init(1); 143 // Register for multi SIM config change. 144 mPcm.registerForMultiSimConfigChange(mHandler, EVENT_MULTI_SIM_CONFIG_CHANGED, null); 145 verify(mHandler, never()).sendMessageAtTime(any(), anyLong()); 146 147 // Try switching to dual SIM. Shouldn't work as we haven't indicated DSDS is supported. 148 mPcm.switchMultiSimConfig(2); 149 verify(mMockRadioConfig, never()).setModemsConfig(anyInt(), any()); 150 151 // Send static capability back to indicate DSDS is supported. 152 clearInvocations(mMockRadioConfig); 153 testGetDsdsCapability(); 154 155 // Try to switch to DSDS. 156 setRebootRequiredForConfigSwitch(false); 157 mPcm.switchMultiSimConfig(2); 158 ArgumentCaptor<Message> captor = ArgumentCaptor.forClass(Message.class); 159 verify(mMockRadioConfig).setModemsConfig(eq(2), captor.capture()); 160 161 // Send message back to indicate switch success. 162 Message message = captor.getValue(); 163 AsyncResult.forMessage(message, null, null); 164 message.sendToTarget(); 165 processAllMessages(); 166 167 // Verify set system property being called. 168 verify(mMi).setMultiSimProperties(2); 169 verify(mMi).notifyPhoneFactoryOnMultiSimConfigChanged(any(), eq(2)); 170 171 // Capture and verify registration notification. 172 verify(mHandler).sendMessageAtTime(captor.capture(), anyLong()); 173 message = captor.getValue(); 174 assertEquals(EVENT_MULTI_SIM_CONFIG_CHANGED, message.what); 175 assertEquals(2, ((AsyncResult) message.obj).result); 176 177 // Capture and verify broadcast. 178 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 179 verify(mContext).sendBroadcast(intentCaptor.capture()); 180 Intent intent = intentCaptor.getValue(); 181 assertEquals(ACTION_MULTI_SIM_CONFIG_CHANGED, intent.getAction()); 182 assertEquals(2, intent.getIntExtra( 183 EXTRA_ACTIVE_SIM_SUPPORTED_COUNT, 0)); 184 185 // Verify RIL notification. 186 verify(mMockCi).onSlotActiveStatusChange(true); 187 } 188 } 189