diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 3f24251..6ddfe94 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -630,5 +630,13 @@
                 <action android:name="android.telephony.data.DataService" />
             </intent-filter>
         </service>
+
+        <provider
+            android:name="ServiceStateProvider"
+            android:authorities="service-state"
+            android:exported="true"
+            android:multiprocess="false"
+            android:singleUser="true"
+            android:writePermission="android.permission.MODIFY_PHONE_STATE"/>
     </application>
 </manifest>
diff --git a/src/com/android/phone/ServiceStateProvider.java b/src/com/android/phone/ServiceStateProvider.java
new file mode 100644
index 0000000..69ea27c
--- /dev/null
+++ b/src/com/android/phone/ServiceStateProvider.java
@@ -0,0 +1,365 @@
+/*
+ * 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.CDMA_DEFAULT_ROAMING_INDICATOR;
+import static android.provider.Telephony.ServiceStateTable.CDMA_ERI_ICON_INDEX;
+import static android.provider.Telephony.ServiceStateTable.CDMA_ERI_ICON_MODE;
+import static android.provider.Telephony.ServiceStateTable.CDMA_ROAMING_INDICATOR;
+import static android.provider.Telephony.ServiceStateTable.CONTENT_URI;
+import static android.provider.Telephony.ServiceStateTable.CSS_INDICATOR;
+import static android.provider.Telephony.ServiceStateTable.DATA_OPERATOR_ALPHA_LONG;
+import static android.provider.Telephony.ServiceStateTable.DATA_OPERATOR_ALPHA_SHORT;
+import static android.provider.Telephony.ServiceStateTable.DATA_OPERATOR_NUMERIC;
+import static android.provider.Telephony.ServiceStateTable.DATA_REG_STATE;
+import static android.provider.Telephony.ServiceStateTable.DATA_ROAMING_TYPE;
+import static android.provider.Telephony.ServiceStateTable.IS_EMERGENCY_ONLY;
+import static android.provider.Telephony.ServiceStateTable.IS_MANUAL_NETWORK_SELECTION;
+import static android.provider.Telephony.ServiceStateTable.IS_USING_CARRIER_AGGREGATION;
+import static android.provider.Telephony.ServiceStateTable.NETWORK_ID;
+import static android.provider.Telephony.ServiceStateTable.OPERATOR_ALPHA_LONG_RAW;
+import static android.provider.Telephony.ServiceStateTable.OPERATOR_ALPHA_SHORT_RAW;
+import static android.provider.Telephony.ServiceStateTable.RIL_DATA_RADIO_TECHNOLOGY;
+import static android.provider.Telephony.ServiceStateTable.RIL_VOICE_RADIO_TECHNOLOGY;
+import static android.provider.Telephony.ServiceStateTable.SERVICE_STATE;
+import static android.provider.Telephony.ServiceStateTable.SYSTEM_ID;
+import static android.provider.Telephony.ServiceStateTable.VOICE_OPERATOR_ALPHA_LONG;
+import static android.provider.Telephony.ServiceStateTable.VOICE_OPERATOR_ALPHA_SHORT;
+import static android.provider.Telephony.ServiceStateTable.VOICE_OPERATOR_NUMERIC;
+import static android.provider.Telephony.ServiceStateTable.VOICE_REG_STATE;
+import static android.provider.Telephony.ServiceStateTable.VOICE_ROAMING_TYPE;
+import static android.provider.Telephony.ServiceStateTable.getUriForSubscriptionId;
+import static android.provider.Telephony.ServiceStateTable.getUriForSubscriptionIdAndField;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.database.MatrixCursor.RowBuilder;
+import android.net.Uri;
+import android.os.Parcel;
+import android.telephony.ServiceState;
+import android.telephony.SubscriptionManager;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.HashMap;
+
+/**
+ * The class to provide base facility to access ServiceState related content,
+ * which is stored in a SQLite database.
+ */
+public class ServiceStateProvider extends ContentProvider {
+    private static final String TAG = "ServiceStateProvider";
+
+    public static final String AUTHORITY = ServiceStateTable.AUTHORITY;
+    public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
+
+    private final HashMap<Integer, ServiceState> mServiceStates = new HashMap<>();
+    private static final String[] sColumns = {
+        VOICE_REG_STATE,
+        DATA_REG_STATE,
+        VOICE_ROAMING_TYPE,
+        DATA_ROAMING_TYPE,
+        VOICE_OPERATOR_ALPHA_LONG,
+        VOICE_OPERATOR_ALPHA_SHORT,
+        VOICE_OPERATOR_NUMERIC,
+        DATA_OPERATOR_ALPHA_LONG,
+        DATA_OPERATOR_ALPHA_SHORT,
+        DATA_OPERATOR_NUMERIC,
+        IS_MANUAL_NETWORK_SELECTION,
+        RIL_VOICE_RADIO_TECHNOLOGY,
+        RIL_DATA_RADIO_TECHNOLOGY,
+        CSS_INDICATOR,
+        NETWORK_ID,
+        SYSTEM_ID,
+        CDMA_ROAMING_INDICATOR,
+        CDMA_DEFAULT_ROAMING_INDICATOR,
+        CDMA_ERI_ICON_INDEX,
+        CDMA_ERI_ICON_MODE,
+        IS_EMERGENCY_ONLY,
+        IS_USING_CARRIER_AGGREGATION,
+        OPERATOR_ALPHA_LONG_RAW,
+        OPERATOR_ALPHA_SHORT_RAW,
+    };
+
+    @Override
+    public boolean onCreate() {
+        return true;
+    }
+
+    /**
+     * Returns the {@link ServiceState} information on specified subscription.
+     *
+     * @param subId whose subscriber id is returned
+     * @return the {@link ServiceState} information on specified subscription.
+     */
+    @VisibleForTesting
+    public ServiceState getServiceState(int subId) {
+        return mServiceStates.get(subId);
+    }
+
+    /**
+     * Returns the system's default subscription id.
+     *
+     * @return the "system" default subscription id.
+     */
+    @VisibleForTesting
+    public int getDefaultSubId() {
+        return SubscriptionManager.getDefaultSubscriptionId();
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        if (uri.isPathPrefixMatch(CONTENT_URI)) {
+            // Parse the subId
+            int subId = 0;
+            try {
+                subId = Integer.parseInt(uri.getLastPathSegment());
+            } catch (NumberFormatException e) {
+                Log.e(TAG, "insert: no subId provided in uri");
+                throw e;
+            }
+            Log.d(TAG, "subId=" + subId);
+
+            // handle DEFAULT_SUBSCRIPTION_ID
+            if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
+                subId = getDefaultSubId();
+            }
+
+            final Parcel p = Parcel.obtain();
+            final byte[] rawBytes = values.getAsByteArray(SERVICE_STATE);
+            p.unmarshall(rawBytes, 0, rawBytes.length);
+            p.setDataPosition(0);
+
+            // create the new service state
+            final ServiceState newSS = ServiceState.CREATOR.createFromParcel(p);
+
+            // notify listeners
+            // if ss is null (e.g. first service state update) we will notify for all fields
+            ServiceState ss = getServiceState(subId);
+            notifyChangeForSubIdAndField(getContext(), ss, newSS, subId);
+            notifyChangeForSubId(getContext(), ss, newSS, subId);
+
+            // store the new service state
+            mServiceStates.put(subId, newSS);
+            return uri;
+        }
+        return null;
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        throw new RuntimeException("Not supported");
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        throw new RuntimeException("Not supported");
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        throw new RuntimeException("Not supported");
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        if (!uri.isPathPrefixMatch(CONTENT_URI)) {
+            throw new IllegalArgumentException("Invalid URI: " + uri);
+        } else {
+            // Parse the subId
+            int subId = 0;
+            try {
+                subId = Integer.parseInt(uri.getLastPathSegment());
+            } catch (NumberFormatException e) {
+                Log.d(TAG, "query: no subId provided in uri, using default.");
+                subId = getDefaultSubId();
+            }
+            Log.d(TAG, "subId=" + subId);
+
+            // handle DEFAULT_SUBSCRIPTION_ID
+            if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
+                subId = getDefaultSubId();
+            }
+
+            // Get the service state
+            ServiceState ss = getServiceState(subId);
+            if (ss == null) {
+                Log.d(TAG, "returning null");
+                return null;
+            }
+
+            // Build the result
+            final int voice_reg_state = ss.getVoiceRegState();
+            final int data_reg_state = ss.getDataRegState();
+            final int voice_roaming_type = ss.getVoiceRoamingType();
+            final int data_roaming_type = ss.getDataRoamingType();
+            final String voice_operator_alpha_long = ss.getOperatorAlphaLong();
+            final String voice_operator_alpha_short = ss.getOperatorAlphaShort();
+            final String voice_operator_numeric = ss.getOperatorNumeric();
+            final String data_operator_alpha_long = ss.getOperatorAlphaLong();
+            final String data_operator_alpha_short = ss.getOperatorAlphaShort();
+            final String data_operator_numeric = ss.getOperatorNumeric();
+            final int is_manual_network_selection = (ss.getIsManualSelection()) ? 1 : 0;
+            final int ril_voice_radio_technology = ss.getRilVoiceRadioTechnology();
+            final int ril_data_radio_technology = ss.getRilDataRadioTechnology();
+            final int css_indicator = ss.getCssIndicator();
+            final int network_id = ss.getCdmaNetworkId();
+            final int system_id = ss.getCdmaSystemId();
+            final int cdma_roaming_indicator = ss.getCdmaRoamingIndicator();
+            final int cdma_default_roaming_indicator = ss.getCdmaDefaultRoamingIndicator();
+            final int cdma_eri_icon_index = ss.getCdmaEriIconIndex();
+            final int cdma_eri_icon_mode = ss.getCdmaEriIconMode();
+            final int is_emergency_only = (ss.isEmergencyOnly()) ? 1 : 0;
+            final int is_using_carrier_aggregation = (ss.isUsingCarrierAggregation()) ? 1 : 0;
+            final String operator_alpha_long_raw = ss.getOperatorAlphaLongRaw();
+            final String operator_alpha_short_raw = ss.getOperatorAlphaShortRaw();
+
+            return buildSingleRowResult(projection, sColumns, new Object[] {
+                    voice_reg_state,
+                    data_reg_state,
+                    voice_roaming_type,
+                    data_roaming_type,
+                    voice_operator_alpha_long,
+                    voice_operator_alpha_short,
+                    voice_operator_numeric,
+                    data_operator_alpha_long,
+                    data_operator_alpha_short,
+                    data_operator_numeric,
+                    is_manual_network_selection,
+                    ril_voice_radio_technology,
+                    ril_data_radio_technology,
+                    css_indicator,
+                    network_id,
+                    system_id,
+                    cdma_roaming_indicator,
+                    cdma_default_roaming_indicator,
+                    cdma_eri_icon_index,
+                    cdma_eri_icon_mode,
+                    is_emergency_only,
+                    is_using_carrier_aggregation,
+                    operator_alpha_long_raw,
+                    operator_alpha_short_raw,
+            });
+        }
+    }
+
+    private static Cursor buildSingleRowResult(String[] projection, String[] availableColumns,
+            Object[] data) {
+        if (projection == null) {
+            projection = availableColumns;
+        }
+        final MatrixCursor c = new MatrixCursor(projection, 1);
+        final RowBuilder row = c.newRow();
+        for (int i = 0; i < c.getColumnCount(); i++) {
+            final String columnName = c.getColumnName(i);
+            boolean found = false;
+            for (int j = 0; j < availableColumns.length; j++) {
+                if (availableColumns[j].equals(columnName)) {
+                    row.add(data[j]);
+                    found = true;
+                    break;
+                }
+            }
+            if (!found) {
+                throw new IllegalArgumentException("Invalid column " + projection[i]);
+            }
+        }
+        return c;
+    }
+
+    /**
+     * Notify interested apps that certain fields of the ServiceState have changed.
+     *
+     * Apps which want to wake when specific fields change can use
+     * JobScheduler's TriggerContentUri.  This replaces the waking functionality of the implicit
+     * broadcast of ACTION_SERVICE_STATE_CHANGED for apps targeting version O.
+     *
+     * We will only notify for certain fields. This is an intentional change from the behavior of
+     * the broadcast. Listeners will be notified when the voice or data registration state or
+     * roaming type changes.
+     */
+    @VisibleForTesting
+    public static void notifyChangeForSubIdAndField(Context context, ServiceState oldSS,
+            ServiceState newSS, int subId) {
+        final boolean firstUpdate = (oldSS == null) ? true : false;
+
+        // for every field, if the field has changed values, notify via the provider
+        if (firstUpdate || voiceRegStateChanged(oldSS, newSS)) {
+            context.getContentResolver().notifyChange(
+                    getUriForSubscriptionIdAndField(subId, VOICE_REG_STATE),
+                    /* observer= */ null, /* syncToNetwork= */ false);
+        }
+        if (firstUpdate || dataRegStateChanged(oldSS, newSS)) {
+            context.getContentResolver().notifyChange(
+                    getUriForSubscriptionIdAndField(subId, DATA_REG_STATE), null, false);
+        }
+        if (firstUpdate || voiceRoamingTypeChanged(oldSS, newSS)) {
+            context.getContentResolver().notifyChange(
+                    getUriForSubscriptionIdAndField(subId, VOICE_ROAMING_TYPE), null, false);
+        }
+        if (firstUpdate || dataRoamingTypeChanged(oldSS, newSS)) {
+            context.getContentResolver().notifyChange(
+                    getUriForSubscriptionIdAndField(subId, DATA_ROAMING_TYPE), null, false);
+        }
+    }
+
+    private static boolean voiceRegStateChanged(ServiceState oldSS, ServiceState newSS) {
+        return oldSS.getVoiceRegState() != newSS.getVoiceRegState();
+    }
+
+    private static boolean dataRegStateChanged(ServiceState oldSS, ServiceState newSS) {
+        return oldSS.getDataRegState() != newSS.getDataRegState();
+    }
+
+    private static boolean voiceRoamingTypeChanged(ServiceState oldSS, ServiceState newSS) {
+        return oldSS.getVoiceRoamingType() != newSS.getVoiceRoamingType();
+    }
+
+    private static boolean dataRoamingTypeChanged(ServiceState oldSS, ServiceState newSS) {
+        return oldSS.getDataRoamingType() != newSS.getDataRoamingType();
+    }
+
+    /**
+     * Notify interested apps that the ServiceState has changed.
+     *
+     * Apps which want to wake when any field in the ServiceState has changed can use
+     * JobScheduler's TriggerContentUri.  This replaces the waking functionality of the implicit
+     * broadcast of ACTION_SERVICE_STATE_CHANGED for apps targeting version O.
+     *
+     * We will only notify for certain fields. This is an intentional change from the behavior of
+     * the broadcast. Listeners will only be notified when the voice/data registration state or
+     * roaming type changes.
+     */
+    @VisibleForTesting
+    public static void notifyChangeForSubId(Context context, ServiceState oldSS, ServiceState newSS,
+            int subId) {
+        // if the voice or data registration or roaming state field has changed values, notify via
+        // the provider.
+        // If oldSS is null and newSS is not (e.g. first update of service state) this will also
+        // notify
+        if (oldSS == null || voiceRegStateChanged(oldSS, newSS) || dataRegStateChanged(oldSS, newSS)
+                || voiceRoamingTypeChanged(oldSS, newSS) || dataRoamingTypeChanged(oldSS, newSS)) {
+            context.getContentResolver().notifyChange(getUriForSubscriptionId(subId), null, false);
+        }
+    }
+}
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);
+    }
+}
