[Mainline] move ServiceStateProvider to TeleService
-add ServiceStateProvider.java from TelephonyProvider
-add ServiceStateProviderTest.java from TelephonyProvider
-modify client/AndroidManifest.xml
-modify tests/Android.bp
Bug: 144486008
Test: atest ServiceStateProviderTest (PASS)
Change-Id: Id51aee376bf519b0a431f5f5caaea99e23fb669b
Merged-In: Id51aee376bf519b0a431f5f5caaea99e23fb669b
diff --git a/tests/Android.bp b/tests/Android.bp
index 22b40b5..7ed234e 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -25,6 +25,7 @@
"telephony-common",
"android.test.base",
"ims-common",
+ "android.test.mock",
],
platform_apis: true,
certificate: "platform",
diff --git a/tests/src/com/android/phone/ServiceStateProviderTest.java b/tests/src/com/android/phone/ServiceStateProviderTest.java
new file mode 100644
index 0000000..5f13389
--- /dev/null
+++ b/tests/src/com/android/phone/ServiceStateProviderTest.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2019 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.phone;
+
+import static android.provider.Telephony.ServiceStateTable;
+import static android.provider.Telephony.ServiceStateTable.getUriForSubscriptionId;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import android.content.Context;
+import android.content.pm.ProviderInfo;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.telephony.ServiceState;
+import android.telephony.SubscriptionManager;
+import android.test.mock.MockContentResolver;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for simple queries of ServiceStateProvider.
+ *
+ * Build, install and run the tests by running the commands below:
+ * runtest --path <dir or file>
+ * runtest --path <dir or file> --test-method <testMethodName>
+ * e.g.)
+ * runtest --path tests/src/com/android/phone/ServiceStateProviderTest.java \
+ * --test-method testGetServiceState
+ */
+public class ServiceStateProviderTest {
+ private static final String TAG = "ServiceStateProviderTest";
+
+ private Context mContext;
+ private MockContentResolver mContentResolver;
+ private ServiceState mTestServiceState;
+ private ServiceState mTestServiceStateForSubId1;
+
+ private final String[] mTestProjection =
+ {
+ ServiceStateTable.VOICE_REG_STATE,
+ ServiceStateTable.DATA_REG_STATE,
+ ServiceStateTable.VOICE_OPERATOR_ALPHA_LONG,
+ ServiceStateTable.VOICE_OPERATOR_ALPHA_SHORT,
+ ServiceStateTable.VOICE_OPERATOR_NUMERIC,
+ ServiceStateTable.DATA_OPERATOR_ALPHA_LONG,
+ ServiceStateTable.DATA_OPERATOR_ALPHA_SHORT,
+ ServiceStateTable.DATA_OPERATOR_NUMERIC,
+ ServiceStateTable.IS_MANUAL_NETWORK_SELECTION,
+ ServiceStateTable.RIL_VOICE_RADIO_TECHNOLOGY,
+ ServiceStateTable.RIL_DATA_RADIO_TECHNOLOGY,
+ ServiceStateTable.CSS_INDICATOR,
+ ServiceStateTable.NETWORK_ID,
+ ServiceStateTable.SYSTEM_ID,
+ ServiceStateTable.CDMA_ROAMING_INDICATOR,
+ ServiceStateTable.CDMA_DEFAULT_ROAMING_INDICATOR,
+ ServiceStateTable.CDMA_ERI_ICON_INDEX,
+ ServiceStateTable.CDMA_ERI_ICON_MODE,
+ ServiceStateTable.IS_EMERGENCY_ONLY,
+ ServiceStateTable.IS_USING_CARRIER_AGGREGATION,
+ ServiceStateTable.OPERATOR_ALPHA_LONG_RAW,
+ ServiceStateTable.OPERATOR_ALPHA_SHORT_RAW,
+ };
+
+ @Before
+ public void setUp() throws Exception {
+ mContext = mock(Context.class);
+ mContentResolver = new MockContentResolver() {
+ @Override
+ public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
+ throw new RuntimeException("notifyChange!");
+ }
+ };
+ doReturn(mContentResolver).when(mContext).getContentResolver();
+
+ mTestServiceState = new ServiceState();
+ mTestServiceState.setStateOutOfService();
+ mTestServiceStateForSubId1 = new ServiceState();
+ mTestServiceStateForSubId1.setStateOff();
+
+ // Mock out the actual phone state
+ ServiceStateProvider provider = new ServiceStateProvider() {
+ @Override
+ public ServiceState getServiceState(int subId) {
+ if (subId == 1) {
+ return mTestServiceStateForSubId1;
+ } else {
+ return mTestServiceState;
+ }
+ }
+
+ @Override
+ public int getDefaultSubId() {
+ return 0;
+ }
+ };
+ ProviderInfo providerInfo = new ProviderInfo();
+ providerInfo.authority = "service-state";
+ provider.attachInfoForTesting(mContext, providerInfo);
+ mContentResolver.addProvider("service-state", provider);
+ }
+
+ @Test
+ @SmallTest
+ public void testQueryServiceStateWithNoSubId() {
+ // Verify that when calling query with no subId in the uri the default ServiceState is
+ // returned.
+ // In this case the subId is set to 0 and the expected service state is
+ // mTestServiceState.
+ verifyServiceStateForSubId(ServiceStateTable.CONTENT_URI, mTestServiceState);
+ }
+
+ @Test
+ @SmallTest
+ public void testGetServiceStateWithDefaultSubId() {
+ // Verify that when calling with the DEFAULT_SUBSCRIPTION_ID the correct ServiceState is
+ // returned
+ // In this case the subId is set to 0 and the expected service state is
+ // mTestServiceState.
+ verifyServiceStateForSubId(
+ getUriForSubscriptionId(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID),
+ mTestServiceState);
+ }
+
+ /**
+ * Test querying the service state for a given subId
+ */
+ @Test
+ @SmallTest
+ public void testGetServiceStateForSubId() {
+ // Verify that when calling with a specific subId the correct ServiceState is returned
+ // In this case the subId is set to 1 and the expected service state is
+ // mTestServiceStateForSubId1
+ verifyServiceStateForSubId(getUriForSubscriptionId(1), mTestServiceStateForSubId1);
+ }
+
+ private void verifyServiceStateForSubId(Uri uri, ServiceState ss) {
+ Cursor cursor = mContentResolver.query(uri, mTestProjection, "",
+ null, null);
+ assertNotNull(cursor);
+ cursor.moveToFirst();
+
+ final int voiceRegState = ss.getVoiceRegState();
+ final int dataRegState = ss.getDataRegState();
+ final String voiceOperatorAlphaLong = ss.getOperatorAlphaLong();
+ final String voiceOperatorAlphaShort = ss.getOperatorAlphaShort();
+ final String voiceOperatorNumeric = ss.getOperatorNumeric();
+ final String dataOperatorAlphaLong = ss.getOperatorAlphaLong();
+ final String dataOperatorAlphaShort = ss.getOperatorAlphaShort();
+ final String dataOperatorNumeric = ss.getOperatorNumeric();
+ final int isManualNetworkSelection = (ss.getIsManualSelection()) ? 1 : 0;
+ final int rilVoiceRadioTechnology = ss.getRilVoiceRadioTechnology();
+ final int rilDataRadioTechnology = ss.getRilDataRadioTechnology();
+ final int cssIndicator = ss.getCssIndicator();
+ final int networkId = ss.getCdmaNetworkId();
+ final int systemId = ss.getCdmaSystemId();
+ final int cdmaRoamingIndicator = ss.getCdmaRoamingIndicator();
+ final int cdmaDefaultRoamingIndicator = ss.getCdmaDefaultRoamingIndicator();
+ final int cdmaEriIconIndex = ss.getCdmaEriIconIndex();
+ final int cdmaEriIconMode = ss.getCdmaEriIconMode();
+ final int isEmergencyOnly = (ss.isEmergencyOnly()) ? 1 : 0;
+ final int isUsingCarrierAggregation = (ss.isUsingCarrierAggregation()) ? 1 : 0;
+ final String operatorAlphaLongRaw = ss.getOperatorAlphaLongRaw();
+ final String operatorAlphaShortRaw = ss.getOperatorAlphaShortRaw();
+
+ assertEquals(voiceRegState, cursor.getInt(0));
+ assertEquals(dataRegState, cursor.getInt(1));
+ assertEquals(voiceOperatorAlphaLong, cursor.getString(2));
+ assertEquals(voiceOperatorAlphaShort, cursor.getString(3));
+ assertEquals(voiceOperatorNumeric, cursor.getString(4));
+ assertEquals(dataOperatorAlphaLong, cursor.getString(5));
+ assertEquals(dataOperatorAlphaShort, cursor.getString(6));
+ assertEquals(dataOperatorNumeric, cursor.getString(7));
+ assertEquals(isManualNetworkSelection, cursor.getInt(8));
+ assertEquals(rilVoiceRadioTechnology, cursor.getInt(9));
+ assertEquals(rilDataRadioTechnology, cursor.getInt(10));
+ assertEquals(cssIndicator, cursor.getInt(11));
+ assertEquals(networkId, cursor.getInt(12));
+ assertEquals(systemId, cursor.getInt(13));
+ assertEquals(cdmaRoamingIndicator, cursor.getInt(14));
+ assertEquals(cdmaDefaultRoamingIndicator, cursor.getInt(15));
+ assertEquals(cdmaEriIconIndex, cursor.getInt(16));
+ assertEquals(cdmaEriIconMode, cursor.getInt(17));
+ assertEquals(isEmergencyOnly, cursor.getInt(18));
+ assertEquals(isUsingCarrierAggregation, cursor.getInt(19));
+ assertEquals(operatorAlphaLongRaw, cursor.getString(20));
+ assertEquals(operatorAlphaShortRaw, cursor.getString(21));
+ }
+
+ /**
+ * Test that we don't notify for certain field changes. (e.g. we don't notify when the NetworkId
+ * or SystemId change) This is an intentional behavior change from the broadcast.
+ */
+ @Test
+ @SmallTest
+ public void testNoNotify() {
+ int subId = 0;
+
+ ServiceState oldSS = new ServiceState();
+ oldSS.setStateOutOfService();
+ oldSS.setCdmaSystemAndNetworkId(1, 1);
+
+ ServiceState newSS = new ServiceState();
+ newSS.setStateOutOfService();
+ newSS.setCdmaSystemAndNetworkId(0, 0);
+
+ // Test that notifyChange is not called for these fields
+ boolean notifyChangeWasCalled = false;
+ try {
+ ServiceStateProvider.notifyChangeForSubIdAndField(mContext, oldSS, newSS, subId);
+ } catch (RuntimeException e) {
+ final String message = e.getMessage();
+ if (message != null && message.equals("notifyChange!")) {
+ notifyChangeWasCalled = true;
+ }
+ }
+ assertFalse(notifyChangeWasCalled);
+ }
+
+ @Test
+ @SmallTest
+ public void testNotifyChanged() {
+ int subId = 0;
+
+ ServiceState oldSS = new ServiceState();
+ oldSS.setStateOutOfService();
+ oldSS.setVoiceRegState(ServiceState.STATE_OUT_OF_SERVICE);
+
+ ServiceState copyOfOldSS = new ServiceState();
+ copyOfOldSS.setStateOutOfService();
+ copyOfOldSS.setVoiceRegState(ServiceState.STATE_OUT_OF_SERVICE);
+
+ ServiceState newSS = new ServiceState();
+ newSS.setStateOutOfService();
+ newSS.setVoiceRegState(ServiceState.STATE_POWER_OFF);
+
+ // Test that notifyChange is not called with no change in notifyChangeForSubIdAndField
+ boolean notifyChangeWasCalled = false;
+ try {
+ ServiceStateProvider.notifyChangeForSubIdAndField(mContext, oldSS, copyOfOldSS, subId);
+ } catch (RuntimeException e) {
+ final String message = e.getMessage();
+ if (message != null && message.equals("notifyChange!")) {
+ notifyChangeWasCalled = true;
+ }
+ }
+ assertFalse(notifyChangeWasCalled);
+
+ // Test that notifyChange is not called with no change in notifyChangeForSubId
+ notifyChangeWasCalled = false;
+ try {
+ ServiceStateProvider.notifyChangeForSubId(mContext, oldSS, copyOfOldSS, subId);
+ } catch (RuntimeException e) {
+ final String message = e.getMessage();
+ if (message != null && message.equals("notifyChange!")) {
+ notifyChangeWasCalled = true;
+ }
+ }
+ assertFalse(notifyChangeWasCalled);
+
+ // Test that notifyChange is called by notifyChangeForSubIdAndField when the voice_reg_state
+ // changes
+ notifyChangeWasCalled = false;
+ try {
+ ServiceStateProvider.notifyChangeForSubIdAndField(mContext, oldSS, newSS, subId);
+ } catch (RuntimeException e) {
+ final String message = e.getMessage();
+ if (message != null && message.equals("notifyChange!")) {
+ notifyChangeWasCalled = true;
+ }
+ }
+ assertTrue(notifyChangeWasCalled);
+
+ // Test that notifyChange is called by notifyChangeForSubId when the voice_reg_state changes
+ notifyChangeWasCalled = false;
+ try {
+ ServiceStateProvider.notifyChangeForSubId(mContext, oldSS, newSS, subId);
+ } catch (RuntimeException e) {
+ final String message = e.getMessage();
+ if (message != null && message.equals("notifyChange!")) {
+ notifyChangeWasCalled = true;
+ }
+ }
+ assertTrue(notifyChangeWasCalled);
+ }
+}