1 /* 2 * Copyright (C) 2022 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.phone; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertTrue; 21 import static org.mockito.Mockito.eq; 22 import static org.mockito.Mockito.when; 23 24 import android.content.ComponentName; 25 import android.telecom.PhoneAccountHandle; 26 import android.telephony.SubscriptionInfo; 27 import android.telephony.SubscriptionManager; 28 29 import androidx.test.runner.AndroidJUnit4; 30 31 import com.android.internal.telephony.GsmCdmaPhone; 32 import com.android.internal.telephony.Phone; 33 import com.android.internal.telephony.PhoneFactory; 34 35 import org.junit.After; 36 import org.junit.Before; 37 import org.junit.Test; 38 import org.junit.runner.RunWith; 39 import org.mockito.Mock; 40 import org.mockito.MockitoAnnotations; 41 42 import java.lang.reflect.Field; 43 import java.util.ArrayList; 44 import java.util.HashMap; 45 46 @RunWith(AndroidJUnit4.class) 47 public class PhoneUtilsTest { 48 @Mock 49 private SubscriptionManager mMockSubscriptionManager; 50 @Mock 51 private SubscriptionInfo mMockSubscriptionInfo; 52 @Mock 53 private GsmCdmaPhone mMockPhone; 54 55 private final int mPhoneAccountHandleIdInteger = 123; 56 private final String mPhoneAccountHandleIdString = "123"; 57 private static final ComponentName PSTN_CONNECTION_SERVICE_COMPONENT = new ComponentName( 58 "com.android.phone", "com.android.services.telephony.TelephonyConnectionService"); 59 private PhoneAccountHandle mPhoneAccountHandleTest = new PhoneAccountHandle( 60 PSTN_CONNECTION_SERVICE_COMPONENT, mPhoneAccountHandleIdString); 61 62 private HashMap<InstanceKey, Object> mOldInstances = new HashMap<InstanceKey, Object>(); 63 64 private ArrayList<InstanceKey> mInstanceKeys = new ArrayList<InstanceKey>(); 65 66 private static class InstanceKey { 67 public final Class mClass; 68 public final String mInstName; 69 public final Object mObj; InstanceKey(final Class c, final String instName, final Object obj)70 InstanceKey(final Class c, final String instName, final Object obj) { 71 mClass = c; 72 mInstName = instName; 73 mObj = obj; 74 } 75 76 @Override hashCode()77 public int hashCode() { 78 return (mClass.getName().hashCode() * 31 + mInstName.hashCode()) * 31; 79 } 80 81 @Override equals(Object obj)82 public boolean equals(Object obj) { 83 if (obj == null || !(obj instanceof InstanceKey)) { 84 return false; 85 } 86 87 InstanceKey other = (InstanceKey) obj; 88 return (other.mClass == mClass && other.mInstName.equals(mInstName) 89 && other.mObj == mObj); 90 } 91 } 92 93 @Before setUp()94 public void setUp() throws Exception { 95 MockitoAnnotations.initMocks(this); 96 when(mMockSubscriptionManager.getActiveSubscriptionInfo( 97 eq(mPhoneAccountHandleIdInteger))).thenReturn(mMockSubscriptionInfo); 98 when(mMockPhone.getSubId()).thenReturn(mPhoneAccountHandleIdInteger); 99 Phone[] mPhones = new Phone[] {mMockPhone}; 100 replaceInstance(PhoneFactory.class, "sPhones", null, mPhones); 101 } 102 103 @After tearDown()104 public void tearDown() throws Exception { 105 restoreInstance(PhoneFactory.class, "sPhones", null); 106 } 107 replaceInstance(final Class c, final String instanceName, final Object obj, final Object newValue)108 protected synchronized void replaceInstance(final Class c, final String instanceName, 109 final Object obj, final Object newValue) 110 throws Exception { 111 Field field = c.getDeclaredField(instanceName); 112 field.setAccessible(true); 113 114 InstanceKey key = new InstanceKey(c, instanceName, obj); 115 if (!mOldInstances.containsKey(key)) { 116 mOldInstances.put(key, field.get(obj)); 117 mInstanceKeys.add(key); 118 } 119 field.set(obj, newValue); 120 } 121 restoreInstance(final Class c, final String instanceName, final Object obj)122 protected synchronized void restoreInstance(final Class c, final String instanceName, 123 final Object obj) throws Exception { 124 InstanceKey key = new InstanceKey(c, instanceName, obj); 125 if (mOldInstances.containsKey(key)) { 126 Field field = c.getDeclaredField(instanceName); 127 field.setAccessible(true); 128 field.set(obj, mOldInstances.get(key)); 129 mOldInstances.remove(key); 130 mInstanceKeys.remove(key); 131 } 132 } 133 134 @Test testIsPhoneAccountActive()135 public void testIsPhoneAccountActive() throws Exception { 136 assertTrue(PhoneUtils.isPhoneAccountActive( 137 mMockSubscriptionManager, mPhoneAccountHandleTest)); 138 } 139 140 @Test testGetPhoneForPhoneAccountHandle()141 public void testGetPhoneForPhoneAccountHandle() throws Exception { 142 assertEquals(mMockPhone, PhoneUtils.getPhoneForPhoneAccountHandle( 143 mPhoneAccountHandleTest)); 144 } 145 146 @Test testMakePstnPhoneAccountHandleWithPrefix()147 public void testMakePstnPhoneAccountHandleWithPrefix() throws Exception { 148 PhoneAccountHandle phoneAccountHandleTest = new PhoneAccountHandle( 149 PSTN_CONNECTION_SERVICE_COMPONENT, mPhoneAccountHandleIdString); 150 assertEquals(phoneAccountHandleTest, PhoneUtils.makePstnPhoneAccountHandleWithPrefix( 151 mPhoneAccountHandleIdString, "", false)); 152 } 153 } 154