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