[Mainline] decouple TelephonyProvider from hidden ServiceState dependencies.

1.Move ServiceStateProvider to TeleService
-move the ServiceStateProvider.java to TeleService
-move the ServiceStateProviderTest.java to TeleService
2.Copy ServiceState's RIL_RADIO_TECHNOLOGY and related function to
TelephonyProvider as a temporary solution.
-copy convertBearerBitmaskToNetworkTypeBitmask(I)I
-copy convertNetworkTypeBitmaskToBearerBitmask(I)I
-copy and refactor bitmaskHasTech(I,I)
-copy and refactor rilRadioTechnologyToNetworkType(I)I

Bug: 144486008
Test: atest TelephonyProviderTest (PASS)
atest ServiceStateProviderTest (PASS)

Change-Id: Ia114fe8b8c1addc1d593f62409ca4a36b09b1956
Merged-In: Ia114fe8b8c1addc1d593f62409ca4a36b09b1956
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d8565eb..3a266e0 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -52,13 +52,6 @@
                   android:singleUser="true"
                   android:multiprocess="false" />
 
-        <provider android:name="ServiceStateProvider"
-                  android:authorities="service-state"
-                  android:exported="true"
-                  android:singleUser="true"
-                  android:writePermission="android.permission.MODIFY_PHONE_STATE"
-                  android:multiprocess="false" />
-
         <!-- This is a singleton provider that is used by all users.
              A new instance is not created for each user. And the db is shared
              as well. -->
diff --git a/src/com/android/providers/telephony/ServiceStateProvider.java b/src/com/android/providers/telephony/ServiceStateProvider.java
deleted file mode 100644
index f707200..0000000
--- a/src/com/android/providers/telephony/ServiceStateProvider.java
+++ /dev/null
@@ -1,353 +0,0 @@
-/* //device/content/providers/telephony/TelephonyProvider.java
-**
-** Copyright 2016, 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.providers.telephony;
-
-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 com.android.internal.telephony.SubscriptionController;
-
-import java.util.HashMap;
-
-
-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;
-    }
-
-    @VisibleForTesting
-    public ServiceState getServiceState(int subId) {
-        return mServiceStates.get(subId);
-    }
-
-    @VisibleForTesting
-    public int getDefaultSubId() {
-        return SubscriptionController.getInstance().getDefaultSubId();
-    }
-
-    @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 targetting 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/src/com/android/providers/telephony/TelephonyProvider.java b/src/com/android/providers/telephony/TelephonyProvider.java
index 6c25832..e8f26fd 100644
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ b/src/com/android/providers/telephony/TelephonyProvider.java
@@ -101,7 +101,7 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Telephony;
-import android.telephony.ServiceState;
+import android.telephony.Annotation;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -254,6 +254,55 @@
 
     private boolean mManagedApnEnforced;
 
+    /**
+     * Available radio technologies for GSM, UMTS and CDMA.
+     * Duplicates the constants from hardware/radio/include/ril.h
+     * This should only be used by agents working with the ril.  Others
+     * should use the equivalent TelephonyManager.NETWORK_TYPE_*
+     */
+    private static final int RIL_RADIO_TECHNOLOGY_UNKNOWN = 0;
+    private static final int RIL_RADIO_TECHNOLOGY_GPRS = 1;
+    private static final int RIL_RADIO_TECHNOLOGY_EDGE = 2;
+    private static final int RIL_RADIO_TECHNOLOGY_UMTS = 3;
+    private static final int RIL_RADIO_TECHNOLOGY_IS95A = 4;
+    private static final int RIL_RADIO_TECHNOLOGY_IS95B = 5;
+    private static final int RIL_RADIO_TECHNOLOGY_1xRTT = 6;
+    private static final int RIL_RADIO_TECHNOLOGY_EVDO_0 = 7;
+    private static final int RIL_RADIO_TECHNOLOGY_EVDO_A = 8;
+    private static final int RIL_RADIO_TECHNOLOGY_HSDPA = 9;
+    private static final int RIL_RADIO_TECHNOLOGY_HSUPA = 10;
+    private static final int RIL_RADIO_TECHNOLOGY_HSPA = 11;
+    private static final int RIL_RADIO_TECHNOLOGY_EVDO_B = 12;
+    private static final int RIL_RADIO_TECHNOLOGY_EHRPD = 13;
+    private static final int RIL_RADIO_TECHNOLOGY_LTE = 14;
+    private static final int RIL_RADIO_TECHNOLOGY_HSPAP = 15;
+
+    /**
+     * GSM radio technology only supports voice. It does not support data.
+     */
+    private static final int RIL_RADIO_TECHNOLOGY_GSM = 16;
+    private static final int RIL_RADIO_TECHNOLOGY_TD_SCDMA = 17;
+
+    /**
+     * IWLAN
+     */
+    private static final int RIL_RADIO_TECHNOLOGY_IWLAN = 18;
+
+    /**
+     * LTE_CA
+     */
+    private static final int RIL_RADIO_TECHNOLOGY_LTE_CA = 19;
+
+    /**
+     * NR(New Radio) 5G.
+     */
+    private static final int  RIL_RADIO_TECHNOLOGY_NR = 20;
+
+    /**
+     * The number of the radio technologies.
+     */
+    private static final int NEXT_RIL_RADIO_TECHNOLOGY = 21;
+
     private static final Map<String, Integer> MVNO_TYPE_STRING_MAP;
 
     static {
@@ -1858,13 +1907,11 @@
                         // Change bearer to a bitmask
                         String bearerStr = c.getString(c.getColumnIndex(BEARER));
                         if (!TextUtils.isEmpty(bearerStr)) {
-                            int bearer_bitmask = ServiceState.getBitmaskForTech(
-                                    Integer.parseInt(bearerStr));
+                            int bearer_bitmask = getBitmaskForTech(Integer.parseInt(bearerStr));
                             cv.put(BEARER_BITMASK, bearer_bitmask);
 
-                            int networkTypeBitmask = ServiceState.getBitmaskForTech(
-                                    ServiceState.rilRadioTechnologyToNetworkType(
-                                            Integer.parseInt(bearerStr)));
+                            int networkTypeBitmask = rilRadioTechnologyToNetworkTypeBitmask(
+                                    Integer.parseInt(bearerStr));
                             cv.put(NETWORK_TYPE_BITMASK, networkTypeBitmask);
                         }
 
@@ -1952,8 +1999,7 @@
                 String fromCursor = c.getString(columnIndex);
                 if (!TextUtils.isEmpty(fromCursor) && fromCursor.matches("\\d+")) {
                     int networkBitmask = Integer.valueOf(fromCursor);
-                    int bearerBitmask = ServiceState.convertNetworkTypeBitmaskToBearerBitmask(
-                            networkBitmask);
+                    int bearerBitmask = convertNetworkTypeBitmaskToBearerBitmask(networkBitmask);
                     cv.put(BEARER_BITMASK, String.valueOf(bearerBitmask));
                 }
                 return;
@@ -1963,8 +2009,7 @@
                 String fromCursor = c.getString(columnIndex);
                 if (!TextUtils.isEmpty(fromCursor) && fromCursor.matches("\\d+")) {
                     int bearerBitmask = Integer.valueOf(fromCursor);
-                    int networkBitmask = ServiceState.convertBearerBitmaskToNetworkTypeBitmask(
-                            bearerBitmask);
+                    int networkBitmask = convertBearerBitmaskToNetworkTypeBitmask(bearerBitmask);
                     cv.put(NETWORK_TYPE_BITMASK, String.valueOf(networkBitmask));
                 }
             }
@@ -2056,22 +2101,20 @@
             int networkTypeBitmask = 0;
             String networkTypeList = parser.getAttributeValue(null, "network_type_bitmask");
             if (networkTypeList != null) {
-                networkTypeBitmask = ServiceState.getBitmaskFromString(networkTypeList);
+                networkTypeBitmask = getBitmaskFromString(networkTypeList);
             }
             map.put(NETWORK_TYPE_BITMASK, networkTypeBitmask);
 
             int bearerBitmask = 0;
             if (networkTypeList != null) {
-                bearerBitmask =
-                        ServiceState.convertNetworkTypeBitmaskToBearerBitmask(networkTypeBitmask);
+                bearerBitmask = convertNetworkTypeBitmaskToBearerBitmask(networkTypeBitmask);
             } else {
                 String bearerList = parser.getAttributeValue(null, "bearer_bitmask");
                 if (bearerList != null) {
-                    bearerBitmask = ServiceState.getBitmaskFromString(bearerList);
+                    bearerBitmask = getBitmaskFromString(bearerList);
                 }
                 // Update the network type bitmask to keep them sync.
-                networkTypeBitmask = ServiceState.convertBearerBitmaskToNetworkTypeBitmask(
-                        bearerBitmask);
+                networkTypeBitmask = convertBearerBitmaskToNetworkTypeBitmask(bearerBitmask);
                 map.put(NETWORK_TYPE_BITMASK, networkTypeBitmask);
             }
             map.put(BEARER_BITMASK, bearerBitmask);
@@ -4010,17 +4053,17 @@
      */
     private static void syncBearerBitmaskAndNetworkTypeBitmask(ContentValues values) {
         if (values.containsKey(NETWORK_TYPE_BITMASK)) {
-            int convertedBitmask = ServiceState.convertNetworkTypeBitmaskToBearerBitmask(
+            int convertedBitmask = convertNetworkTypeBitmaskToBearerBitmask(
                     values.getAsInteger(NETWORK_TYPE_BITMASK));
             if (values.containsKey(BEARER_BITMASK)
                     && convertedBitmask != values.getAsInteger(BEARER_BITMASK)) {
                 loge("Network type bitmask and bearer bitmask are not compatible.");
             }
-            values.put(BEARER_BITMASK, ServiceState.convertNetworkTypeBitmaskToBearerBitmask(
+            values.put(BEARER_BITMASK, convertNetworkTypeBitmaskToBearerBitmask(
                     values.getAsInteger(NETWORK_TYPE_BITMASK)));
         } else {
             if (values.containsKey(BEARER_BITMASK)) {
-                int convertedBitmask = ServiceState.convertBearerBitmaskToNetworkTypeBitmask(
+                int convertedBitmask = convertBearerBitmaskToNetworkTypeBitmask(
                         values.getAsInteger(BEARER_BITMASK));
                 values.put(NETWORK_TYPE_BITMASK, convertedBitmask);
             }
@@ -4045,4 +4088,135 @@
         Integer mvnoTypeInt = MVNO_TYPE_STRING_MAP.get(mvnoTypeString);
         return  mvnoTypeInt == null ? UNSPECIFIED_INT : mvnoTypeInt;
     }
+
+    private static int getBitmaskFromString(String bearerList) {
+        String[] bearers = bearerList.split("\\|");
+        int bearerBitmask = 0;
+        for (String bearer : bearers) {
+            int bearerInt = 0;
+            try {
+                bearerInt = Integer.parseInt(bearer.trim());
+            } catch (NumberFormatException nfe) {
+                return 0;
+            }
+
+            if (bearerInt == 0) {
+                return 0;
+            }
+            bearerBitmask |= getBitmaskForTech(bearerInt);
+        }
+        return bearerBitmask;
+    }
+
+    /**
+     * Transform RIL radio technology value to Network
+     * type bitmask{@link android.telephony.TelephonyManager.NetworkTypeBitMask}.
+     *
+     * @param rat The RIL radio technology.
+     * @return The network type
+     * bitmask{@link android.telephony.TelephonyManager.NetworkTypeBitMask}.
+     */
+    private static int rilRadioTechnologyToNetworkTypeBitmask(int rat) {
+        switch (rat) {
+            case RIL_RADIO_TECHNOLOGY_GPRS:
+                return (int) TelephonyManager.NETWORK_TYPE_BITMASK_GPRS;
+            case RIL_RADIO_TECHNOLOGY_EDGE:
+                return (int) TelephonyManager.NETWORK_TYPE_BITMASK_EDGE;
+            case RIL_RADIO_TECHNOLOGY_UMTS:
+                return (int) TelephonyManager.NETWORK_TYPE_BITMASK_UMTS;
+            case RIL_RADIO_TECHNOLOGY_HSDPA:
+                return (int) TelephonyManager.NETWORK_TYPE_BITMASK_HSDPA;
+            case RIL_RADIO_TECHNOLOGY_HSUPA:
+                return (int) TelephonyManager.NETWORK_TYPE_BITMASK_HSUPA;
+            case RIL_RADIO_TECHNOLOGY_HSPA:
+                return (int) TelephonyManager.NETWORK_TYPE_BITMASK_HSPA;
+            case RIL_RADIO_TECHNOLOGY_IS95A:
+            case RIL_RADIO_TECHNOLOGY_IS95B:
+                return (int) TelephonyManager.NETWORK_TYPE_BITMASK_CDMA;
+            case RIL_RADIO_TECHNOLOGY_1xRTT:
+                return (int) TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT;
+            case RIL_RADIO_TECHNOLOGY_EVDO_0:
+                return (int) TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_0;
+            case RIL_RADIO_TECHNOLOGY_EVDO_A:
+                return (int) TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_A;
+            case RIL_RADIO_TECHNOLOGY_EVDO_B:
+                return (int) TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_B;
+            case RIL_RADIO_TECHNOLOGY_EHRPD:
+                return (int) TelephonyManager.NETWORK_TYPE_BITMASK_EHRPD;
+            case RIL_RADIO_TECHNOLOGY_LTE:
+                return (int) TelephonyManager.NETWORK_TYPE_BITMASK_LTE;
+            case RIL_RADIO_TECHNOLOGY_HSPAP:
+                return (int) TelephonyManager.NETWORK_TYPE_BITMASK_HSPAP;
+            case RIL_RADIO_TECHNOLOGY_GSM:
+                return (int) TelephonyManager.NETWORK_TYPE_BITMASK_GSM;
+            case RIL_RADIO_TECHNOLOGY_TD_SCDMA:
+                return (int) TelephonyManager.NETWORK_TYPE_BITMASK_TD_SCDMA;
+            case RIL_RADIO_TECHNOLOGY_IWLAN:
+                return (int) TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN;
+            case RIL_RADIO_TECHNOLOGY_LTE_CA:
+                return (int) TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA;
+            case RIL_RADIO_TECHNOLOGY_NR:
+                return (int) TelephonyManager.NETWORK_TYPE_BITMASK_NR;
+            default:
+                return (int) TelephonyManager.NETWORK_TYPE_BITMASK_UNKNOWN;
+        }
+    }
+
+    /**
+     * Convert network type bitmask to bearer bitmask.
+     *
+     * @param networkTypeBitmask The network type bitmask value
+     * @return The bearer bitmask value.
+     */
+    private static int convertNetworkTypeBitmaskToBearerBitmask(int networkTypeBitmask) {
+        if (networkTypeBitmask == 0) {
+            return 0;
+        }
+
+        int bearerBitmask = 0;
+        for (int bearerInt = 0; bearerInt < NEXT_RIL_RADIO_TECHNOLOGY; bearerInt++) {
+            if (bitmaskHasTarget(networkTypeBitmask,
+                    rilRadioTechnologyToNetworkTypeBitmask(bearerInt))) {
+                bearerBitmask |= getBitmaskForTech(bearerInt);
+            }
+        }
+        return bearerBitmask;
+    }
+
+    /**
+     * Convert bearer bitmask to network type bitmask.
+     *
+     * @param bearerBitmask The bearer bitmask value.
+     * @return The network type bitmask value.
+     */
+    private static int convertBearerBitmaskToNetworkTypeBitmask(int bearerBitmask) {
+        if (bearerBitmask == 0) {
+            return 0;
+        }
+
+        int networkTypeBitmask = 0;
+        for (int bearerUnitInt = 0; bearerUnitInt < NEXT_RIL_RADIO_TECHNOLOGY; bearerUnitInt++) {
+            int bearerUnitBitmask = getBitmaskForTech(bearerUnitInt);
+            if (bitmaskHasTarget(bearerBitmask, bearerUnitBitmask)) {
+                networkTypeBitmask |= rilRadioTechnologyToNetworkTypeBitmask(bearerUnitInt);
+            }
+        }
+        return networkTypeBitmask;
+    }
+
+    private static boolean bitmaskHasTarget(int bearerBitmask, int targetBitmask) {
+        if (bearerBitmask == 0) {
+            return true;
+        } else if (targetBitmask != 0) {
+            return ((bearerBitmask & targetBitmask) != 0);
+        }
+        return false;
+    }
+
+    private static int getBitmaskForTech(int radioTech) {
+        if (radioTech >= 1) {
+            return (1 << (radioTech - 1));
+        }
+        return 0;
+    }
 }
diff --git a/tests/src/com/android/providers/telephony/ServiceStateProviderTest.java b/tests/src/com/android/providers/telephony/ServiceStateProviderTest.java
deleted file mode 100644
index 0cd66e3..0000000
--- a/tests/src/com/android/providers/telephony/ServiceStateProviderTest.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright (C) 2016 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.providers.telephony;
-
-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;
-import org.mockito.Mock;
-
-/**
- * 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/providers/telephony/ServiceStateProviderTest.java \
- *                 --test-method testGetServiceState
- */
-public class ServiceStateProviderTest {
-    private static final String TAG = "ServiceStateProviderTest";
-
-    private Context mContext;
-    private MockContentResolver mContentResolver;
-    private ServiceState testServiceState;
-    private ServiceState testServiceStateForSubId1;
-
-    private final String[] testProjection =
-    {
-        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();
-
-        testServiceState = new ServiceState();
-        testServiceState.setStateOutOfService();
-        testServiceStateForSubId1 = new ServiceState();
-        testServiceStateForSubId1.setStateOff();
-
-        // Mock out the actual phone state
-        ServiceStateProvider provider = new ServiceStateProvider() {
-            @Override
-            public ServiceState getServiceState(int subId) {
-                if (subId == 1) {
-                    return testServiceStateForSubId1;
-                } else {
-                    return testServiceState;
-                }
-            }
-
-            @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
-        // testServiceState.
-        verifyServiceStateForSubId(ServiceStateTable.CONTENT_URI, testServiceState);
-    }
-
-    @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
-        // testServiceState.
-        verifyServiceStateForSubId(
-                getUriForSubscriptionId(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID),
-                testServiceState);
-    }
-
-    /**
-     * 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
-        // testServiceStateForSubId1
-        verifyServiceStateForSubId(getUriForSubscriptionId(1), testServiceStateForSubId1);
-    }
-
-    private void verifyServiceStateForSubId(Uri uri, ServiceState ss) {
-        Cursor cursor = mContentResolver.query(uri, testProjection, "",
-                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);
-    }
-}