From 956c6015dac38010771f309439bb1e59579bf3d0 Mon Sep 17 00:00:00 2001 From: chen xu Date: Sun, 11 Nov 2018 19:03:11 -0800 Subject: integrate carrier id to defaultcarrierService 1. load file named after carrier id then fallback to read from legacy mccmnc. 2. TODO, migrate assets file to carrier id. Bug: 110559381 Change-Id: If07535509c7dae8cec6b6bb1e71dc02f55937ed7 --- .../carrierconfig/DefaultCarrierConfigService.java | 98 +++++++++++++++++----- 1 file changed, 79 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/com/android/carrierconfig/DefaultCarrierConfigService.java b/src/com/android/carrierconfig/DefaultCarrierConfigService.java index c3a8095..48bc8c1 100644 --- a/src/com/android/carrierconfig/DefaultCarrierConfigService.java +++ b/src/com/android/carrierconfig/DefaultCarrierConfigService.java @@ -1,11 +1,10 @@ package com.android.carrierconfig; -import android.content.Context; +import android.annotation.Nullable; import android.os.Build; import android.os.PersistableBundle; import android.service.carrier.CarrierIdentifier; import android.service.carrier.CarrierService; -import android.telephony.CarrierConfigManager; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; @@ -14,11 +13,7 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserFactory; -import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -48,10 +43,18 @@ public class DefaultCarrierConfigService extends CarrierService { /** * Returns per-network overrides for carrier configuration. * - * This returns a carrier config bundle appropriate for the given network by reading data from - * files in our assets folder. First we look for a file named after the MCC+MNC of {@code id} - * and then we read res/xml/vendor.xml. Both files may contain multiple bundles with filters on - * them. All the matching bundles are flattened to return one carrier config bundle. + * This returns a carrier config bundle appropriate for the given carrier by reading data from + * files in our assets folder. First we look for file named after + * carrier_config__.xml if carrier id is not + * {@link TelephonyManager#UNKNOWN_CARRIER_ID}. Note is to improve the + * readability which should not be used to search asset files. If there is no configuration, + * then we look for a file named after the MCC+MNC of {@code id} as a fallback. Last, we read + * res/xml/vendor.xml. + * + * carrierid.xml doesn't support multiple bundles with filters as each carrier including MVNOs + * has its own config file named after its carrier id. + * Both vendor.xml and MCC+MNC.xml files may contain multiple bundles with filters on them. + * All the matching bundles are flattened to return one carrier config bundle. */ @Override public PersistableBundle onLoadConfig(CarrierIdentifier id) { @@ -61,8 +64,7 @@ public class DefaultCarrierConfigService extends CarrierService { return null; } - - PersistableBundle config = null; + PersistableBundle config = new PersistableBundle(); try { synchronized (this) { if (mFactory == null) { @@ -71,9 +73,42 @@ public class DefaultCarrierConfigService extends CarrierService { } XmlPullParser parser = mFactory.newPullParser(); - String fileName = "carrier_config_" + id.getMcc() + id.getMnc() + ".xml"; - parser.setInput(getApplicationContext().getAssets().open(fileName), "utf-8"); - config = readConfigFromXml(parser, id); + if (id.getCarrierId() != TelephonyManager.UNKNOWN_CARRIER_ID) { + PersistableBundle configByCarrierId = new PersistableBundle(); + PersistableBundle configByPreciseCarrierId = new PersistableBundle(); + PersistableBundle configByMccMncFallBackCarrierId = new PersistableBundle(); + int mccmncCarrierId = TelephonyManager.from(getApplicationContext()) + .getCarrierIdFromMccMnc(id.getMcc() + id.getMnc()); + for (String file : getApplicationContext().getAssets().list("")) { + if (file.startsWith("carrier_config_" + id.getPreciseCarrierId() + "_")) { + parser.setInput(getApplicationContext().getAssets().open(file), "utf-8"); + configByPreciseCarrierId = readConfigFromXml(parser, null); + break; + } else if (file.startsWith("carrier_config_" + id.getCarrierId() + "_")) { + parser.setInput(getApplicationContext().getAssets().open(file), "utf-8"); + configByCarrierId = readConfigFromXml(parser, null); + } else if (file.startsWith("carrier_config_" + mccmncCarrierId + "_")) { + parser.setInput(getApplicationContext().getAssets().open(file), "utf-8"); + configByMccMncFallBackCarrierId = readConfigFromXml(parser, null); + } + } + + // priority: precise carrier id > carrier id > mccmnc fallback carrier id + if (!configByPreciseCarrierId.isEmpty()) { + config = configByPreciseCarrierId; + } else if (!configByCarrierId.isEmpty()) { + config = configByCarrierId; + } else if (!configByMccMncFallBackCarrierId.isEmpty()) { + config = configByMccMncFallBackCarrierId; + } + } + if (config.isEmpty()) { + // fallback to use mccmnc.xml when there is no carrier id named configuration found. + parser.setInput(getApplicationContext().getAssets().open( + "carrier_config_" + id.getMcc() + id.getMnc() + ".xml"), "utf-8"); + config = readConfigFromXml(parser, id); + } + } catch (IOException | XmlPullParserException e) { Log.d(TAG, e.toString()); @@ -98,7 +133,9 @@ public class DefaultCarrierConfigService extends CarrierService { * Parses an XML document and returns a PersistableBundle. * *

This function iterates over each {@code } node in the XML document and - * parses it into a bundle if its filters match {@code id}. The format of XML bundles is defined + * parses it into a bundle if its filters match {@code id}. XML documents named after carrier id + * doesn't support filter match as each carrier including MVNOs will have its own config file. + * The format of XML bundles is defined * by {@link PersistableBundle#restoreFromXml}. All the matching bundles will be flattened and * returned as a single bundle.

* @@ -115,11 +152,25 @@ public class DefaultCarrierConfigService extends CarrierService { * * }

* + *

Here is another example document in vendor.xml. + *

{@code
+     * 
+     *     
+     *         
+     *     
+     *     
+     *         
+     *     
+     * 
+     * }

+ * * @param parser an XmlPullParser pointing at the beginning of the document. - * @param id the details of the SIM operator used to filter parts of the document + * @param id the details of the SIM operator used to filter parts of the document. If read from + * file named after carrier id, this will be set to {@null code} as no filter match + * needed. * @return a possibly empty PersistableBundle containing the config values. */ - static PersistableBundle readConfigFromXml(XmlPullParser parser, CarrierIdentifier id) + static PersistableBundle readConfigFromXml(XmlPullParser parser, @Nullable CarrierIdentifier id) throws IOException, XmlPullParserException { PersistableBundle config = new PersistableBundle(); @@ -133,7 +184,7 @@ public class DefaultCarrierConfigService extends CarrierService { while (((event = parser.next()) != XmlPullParser.END_DOCUMENT)) { if (event == XmlPullParser.START_TAG && "carrier_config".equals(parser.getName())) { // Skip this fragment if it has filters that don't match. - if (!checkFilters(parser, id)) { + if (id != null && !checkFilters(parser, id)) { continue; } PersistableBundle configFragment = PersistableBundle.restoreFromXml(parser); @@ -159,6 +210,8 @@ public class DefaultCarrierConfigService extends CarrierService { *
  • spn: {@link CarrierIdentifier#getSpn}
  • *
  • imsi: {@link CarrierIdentifier#getImsi}
  • *
  • device: {@link Build.DEVICE}
  • + *
  • cid: {@link CarrierIdentifier#getCarrierId()} + * or {@link CarrierIdentifier#getPreciseCarrierId()}
  • * *

    * @@ -199,6 +252,13 @@ public class DefaultCarrierConfigService extends CarrierService { case "device": result = result && value.equalsIgnoreCase(Build.DEVICE); break; + case "cid": + result = result && (value.equals(id.getCarrierId()) + || value.equals(id.getPreciseCarrierId())); + break; + case "name": + // name is used together with cid for readability. ignore for filter. + break; default: Log.e(TAG, "Unknown attribute " + attribute + "=" + value); result = false; -- cgit v1.2.3