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.phone; 18 19 import static android.provider.Telephony.ServiceStateTable; 20 import static android.provider.Telephony.ServiceStateTable.getUriForSubscriptionId; 21 22 import static org.junit.Assert.assertEquals; 23 import static org.junit.Assert.assertFalse; 24 import static org.junit.Assert.assertNotNull; 25 import static org.junit.Assert.assertTrue; 26 import static org.mockito.Mockito.doReturn; 27 import static org.mockito.Mockito.mock; 28 29 import android.content.Context; 30 import android.content.pm.ProviderInfo; 31 import android.database.ContentObserver; 32 import android.database.Cursor; 33 import android.net.Uri; 34 import android.telephony.ServiceState; 35 import android.telephony.SubscriptionManager; 36 import android.test.mock.MockContentResolver; 37 import android.test.suitebuilder.annotation.SmallTest; 38 39 import org.junit.Before; 40 import org.junit.Test; 41 42 /** 43 * Tests for simple queries of ServiceStateProvider. 44 * 45 * Build, install and run the tests by running the commands below: 46 * runtest --path <dir or file> 47 * runtest --path <dir or file> --test-method <testMethodName> 48 * e.g.) 49 * runtest --path tests/src/com/android/phone/ServiceStateProviderTest.java \ 50 * --test-method testGetServiceState 51 */ 52 public class ServiceStateProviderTest { 53 private static final String TAG = "ServiceStateProviderTest"; 54 55 private Context mContext; 56 private MockContentResolver mContentResolver; 57 private ServiceState mTestServiceState; 58 private ServiceState mTestServiceStateForSubId1; 59 60 private final String[] mTestProjection = 61 { 62 ServiceStateTable.VOICE_REG_STATE, 63 ServiceStateTable.DATA_REG_STATE, 64 ServiceStateTable.VOICE_OPERATOR_ALPHA_LONG, 65 ServiceStateTable.VOICE_OPERATOR_ALPHA_SHORT, 66 ServiceStateTable.VOICE_OPERATOR_NUMERIC, 67 ServiceStateTable.DATA_OPERATOR_ALPHA_LONG, 68 ServiceStateTable.DATA_OPERATOR_ALPHA_SHORT, 69 ServiceStateTable.DATA_OPERATOR_NUMERIC, 70 ServiceStateTable.IS_MANUAL_NETWORK_SELECTION, 71 ServiceStateTable.RIL_VOICE_RADIO_TECHNOLOGY, 72 ServiceStateTable.RIL_DATA_RADIO_TECHNOLOGY, 73 ServiceStateTable.CSS_INDICATOR, 74 ServiceStateTable.NETWORK_ID, 75 ServiceStateTable.SYSTEM_ID, 76 ServiceStateTable.CDMA_ROAMING_INDICATOR, 77 ServiceStateTable.CDMA_DEFAULT_ROAMING_INDICATOR, 78 ServiceStateTable.CDMA_ERI_ICON_INDEX, 79 ServiceStateTable.CDMA_ERI_ICON_MODE, 80 ServiceStateTable.IS_EMERGENCY_ONLY, 81 ServiceStateTable.IS_USING_CARRIER_AGGREGATION, 82 ServiceStateTable.OPERATOR_ALPHA_LONG_RAW, 83 ServiceStateTable.OPERATOR_ALPHA_SHORT_RAW, 84 }; 85 86 @Before setUp()87 public void setUp() throws Exception { 88 mContext = mock(Context.class); 89 mContentResolver = new MockContentResolver() { 90 @Override 91 public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) { 92 throw new RuntimeException("notifyChange!"); 93 } 94 }; 95 doReturn(mContentResolver).when(mContext).getContentResolver(); 96 97 mTestServiceState = new ServiceState(); 98 mTestServiceState.setStateOutOfService(); 99 mTestServiceStateForSubId1 = new ServiceState(); 100 mTestServiceStateForSubId1.setStateOff(); 101 102 // Mock out the actual phone state 103 ServiceStateProvider provider = new ServiceStateProvider() { 104 @Override 105 public ServiceState getServiceState(int subId) { 106 if (subId == 1) { 107 return mTestServiceStateForSubId1; 108 } else { 109 return mTestServiceState; 110 } 111 } 112 113 @Override 114 public int getDefaultSubId() { 115 return 0; 116 } 117 }; 118 ProviderInfo providerInfo = new ProviderInfo(); 119 providerInfo.authority = "service-state"; 120 provider.attachInfoForTesting(mContext, providerInfo); 121 mContentResolver.addProvider("service-state", provider); 122 } 123 124 @Test 125 @SmallTest testQueryServiceStateWithNoSubId()126 public void testQueryServiceStateWithNoSubId() { 127 // Verify that when calling query with no subId in the uri the default ServiceState is 128 // returned. 129 // In this case the subId is set to 0 and the expected service state is 130 // mTestServiceState. 131 verifyServiceStateForSubId(ServiceStateTable.CONTENT_URI, mTestServiceState); 132 } 133 134 @Test 135 @SmallTest testGetServiceStateWithDefaultSubId()136 public void testGetServiceStateWithDefaultSubId() { 137 // Verify that when calling with the DEFAULT_SUBSCRIPTION_ID the correct ServiceState is 138 // returned 139 // In this case the subId is set to 0 and the expected service state is 140 // mTestServiceState. 141 verifyServiceStateForSubId( 142 getUriForSubscriptionId(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID), 143 mTestServiceState); 144 } 145 146 /** 147 * Test querying the service state for a given subId 148 */ 149 @Test 150 @SmallTest testGetServiceStateForSubId()151 public void testGetServiceStateForSubId() { 152 // Verify that when calling with a specific subId the correct ServiceState is returned 153 // In this case the subId is set to 1 and the expected service state is 154 // mTestServiceStateForSubId1 155 verifyServiceStateForSubId(getUriForSubscriptionId(1), mTestServiceStateForSubId1); 156 } 157 verifyServiceStateForSubId(Uri uri, ServiceState ss)158 private void verifyServiceStateForSubId(Uri uri, ServiceState ss) { 159 Cursor cursor = mContentResolver.query(uri, mTestProjection, "", 160 null, null); 161 assertNotNull(cursor); 162 cursor.moveToFirst(); 163 164 final int voiceRegState = ss.getState(); 165 final int dataRegState = ss.getDataRegistrationState(); 166 final String voiceOperatorAlphaLong = ss.getOperatorAlphaLong(); 167 final String voiceOperatorAlphaShort = ss.getOperatorAlphaShort(); 168 final String voiceOperatorNumeric = ss.getOperatorNumeric(); 169 final String dataOperatorAlphaLong = ss.getOperatorAlphaLong(); 170 final String dataOperatorAlphaShort = ss.getOperatorAlphaShort(); 171 final String dataOperatorNumeric = ss.getOperatorNumeric(); 172 final int isManualNetworkSelection = (ss.getIsManualSelection()) ? 1 : 0; 173 final int rilVoiceRadioTechnology = ss.getRilVoiceRadioTechnology(); 174 final int rilDataRadioTechnology = ss.getRilDataRadioTechnology(); 175 final int cssIndicator = ss.getCssIndicator(); 176 final int networkId = ss.getCdmaNetworkId(); 177 final int systemId = ss.getCdmaSystemId(); 178 final int cdmaRoamingIndicator = ss.getCdmaRoamingIndicator(); 179 final int cdmaDefaultRoamingIndicator = ss.getCdmaDefaultRoamingIndicator(); 180 final int cdmaEriIconIndex = ss.getCdmaEriIconIndex(); 181 final int cdmaEriIconMode = ss.getCdmaEriIconMode(); 182 final int isEmergencyOnly = (ss.isEmergencyOnly()) ? 1 : 0; 183 final int isUsingCarrierAggregation = (ss.isUsingCarrierAggregation()) ? 1 : 0; 184 final String operatorAlphaLongRaw = ss.getOperatorAlphaLongRaw(); 185 final String operatorAlphaShortRaw = ss.getOperatorAlphaShortRaw(); 186 187 assertEquals(voiceRegState, cursor.getInt(0)); 188 assertEquals(dataRegState, cursor.getInt(1)); 189 assertEquals(voiceOperatorAlphaLong, cursor.getString(2)); 190 assertEquals(voiceOperatorAlphaShort, cursor.getString(3)); 191 assertEquals(voiceOperatorNumeric, cursor.getString(4)); 192 assertEquals(dataOperatorAlphaLong, cursor.getString(5)); 193 assertEquals(dataOperatorAlphaShort, cursor.getString(6)); 194 assertEquals(dataOperatorNumeric, cursor.getString(7)); 195 assertEquals(isManualNetworkSelection, cursor.getInt(8)); 196 assertEquals(rilVoiceRadioTechnology, cursor.getInt(9)); 197 assertEquals(rilDataRadioTechnology, cursor.getInt(10)); 198 assertEquals(cssIndicator, cursor.getInt(11)); 199 assertEquals(networkId, cursor.getInt(12)); 200 assertEquals(systemId, cursor.getInt(13)); 201 assertEquals(cdmaRoamingIndicator, cursor.getInt(14)); 202 assertEquals(cdmaDefaultRoamingIndicator, cursor.getInt(15)); 203 assertEquals(cdmaEriIconIndex, cursor.getInt(16)); 204 assertEquals(cdmaEriIconMode, cursor.getInt(17)); 205 assertEquals(isEmergencyOnly, cursor.getInt(18)); 206 assertEquals(isUsingCarrierAggregation, cursor.getInt(19)); 207 assertEquals(operatorAlphaLongRaw, cursor.getString(20)); 208 assertEquals(operatorAlphaShortRaw, cursor.getString(21)); 209 } 210 211 /** 212 * Test that we don't notify for certain field changes. (e.g. we don't notify when the NetworkId 213 * or SystemId change) This is an intentional behavior change from the broadcast. 214 */ 215 @Test 216 @SmallTest testNoNotify()217 public void testNoNotify() { 218 int subId = 0; 219 220 ServiceState oldSS = new ServiceState(); 221 oldSS.setStateOutOfService(); 222 oldSS.setCdmaSystemAndNetworkId(1, 1); 223 224 ServiceState newSS = new ServiceState(); 225 newSS.setStateOutOfService(); 226 newSS.setCdmaSystemAndNetworkId(0, 0); 227 228 // Test that notifyChange is not called for these fields 229 boolean notifyChangeWasCalled = false; 230 try { 231 ServiceStateProvider.notifyChangeForSubIdAndField(mContext, oldSS, newSS, subId); 232 } catch (RuntimeException e) { 233 final String message = e.getMessage(); 234 if (message != null && message.equals("notifyChange!")) { 235 notifyChangeWasCalled = true; 236 } 237 } 238 assertFalse(notifyChangeWasCalled); 239 } 240 241 @Test 242 @SmallTest testNotifyChanged()243 public void testNotifyChanged() { 244 int subId = 0; 245 246 ServiceState oldSS = new ServiceState(); 247 oldSS.setStateOutOfService(); 248 oldSS.setVoiceRegState(ServiceState.STATE_OUT_OF_SERVICE); 249 250 ServiceState copyOfOldSS = new ServiceState(); 251 copyOfOldSS.setStateOutOfService(); 252 copyOfOldSS.setVoiceRegState(ServiceState.STATE_OUT_OF_SERVICE); 253 254 ServiceState newSS = new ServiceState(); 255 newSS.setStateOutOfService(); 256 newSS.setVoiceRegState(ServiceState.STATE_POWER_OFF); 257 258 // Test that notifyChange is not called with no change in notifyChangeForSubIdAndField 259 boolean notifyChangeWasCalled = false; 260 try { 261 ServiceStateProvider.notifyChangeForSubIdAndField(mContext, oldSS, copyOfOldSS, subId); 262 } catch (RuntimeException e) { 263 final String message = e.getMessage(); 264 if (message != null && message.equals("notifyChange!")) { 265 notifyChangeWasCalled = true; 266 } 267 } 268 assertFalse(notifyChangeWasCalled); 269 270 // Test that notifyChange is not called with no change in notifyChangeForSubId 271 notifyChangeWasCalled = false; 272 try { 273 ServiceStateProvider.notifyChangeForSubId(mContext, oldSS, copyOfOldSS, subId); 274 } catch (RuntimeException e) { 275 final String message = e.getMessage(); 276 if (message != null && message.equals("notifyChange!")) { 277 notifyChangeWasCalled = true; 278 } 279 } 280 assertFalse(notifyChangeWasCalled); 281 282 // Test that notifyChange is called by notifyChangeForSubIdAndField when the voice_reg_state 283 // changes 284 notifyChangeWasCalled = false; 285 try { 286 ServiceStateProvider.notifyChangeForSubIdAndField(mContext, oldSS, newSS, subId); 287 } catch (RuntimeException e) { 288 final String message = e.getMessage(); 289 if (message != null && message.equals("notifyChange!")) { 290 notifyChangeWasCalled = true; 291 } 292 } 293 assertTrue(notifyChangeWasCalled); 294 295 // Test that notifyChange is called by notifyChangeForSubId when the voice_reg_state changes 296 notifyChangeWasCalled = false; 297 try { 298 ServiceStateProvider.notifyChangeForSubId(mContext, oldSS, newSS, subId); 299 } catch (RuntimeException e) { 300 final String message = e.getMessage(); 301 if (message != null && message.equals("notifyChange!")) { 302 notifyChangeWasCalled = true; 303 } 304 } 305 assertTrue(notifyChangeWasCalled); 306 } 307 } 308