[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);
- }
-}