From bbec7b6a5f3bcab8cc9138103b9a76ebcdd8a2cb Mon Sep 17 00:00:00 2001 From: Rambo Wang Date: Tue, 23 Nov 2021 08:02:59 -0800 Subject: [PATCH] Support subscription for CarrierService#onLoadConfig CarrierService#onLoadConfig is called from platform to carrier service to load carrier-specific configuration values. In case when the multiple subscriptions are supported for the same carrier (e.g. Fi on pSIM + Fi on eSIM case), the current API is not able to distinguish on which subscription the carrier config should be loaded. The subscription parameter introduced in the API can resolve the problem. If carrier app has no need to distinguish configs by subscriptions, it can simply ignore overriding the new version of the API. Bug: 131697791 Test: atest CarrierServiceTest CTS-Coverage-Bug: 210143342 Change-Id: Id7cd75c24f01119749cb5bf31d4335c638547aaf --- core/api/current.txt | 3 +- .../service/carrier/CarrierService.java | 70 +++++++++++++++++-- .../service/carrier/ICarrierService.aidl | 2 +- 3 files changed, 69 insertions(+), 6 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index c3b5b943477f..83e5df781f19 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -38283,7 +38283,8 @@ package android.service.carrier { ctor public CarrierService(); method public final void notifyCarrierNetworkChange(boolean); method @CallSuper public android.os.IBinder onBind(android.content.Intent); - method public abstract android.os.PersistableBundle onLoadConfig(android.service.carrier.CarrierIdentifier); + method @Deprecated public abstract android.os.PersistableBundle onLoadConfig(android.service.carrier.CarrierIdentifier); + method @Nullable public android.os.PersistableBundle onLoadConfig(int, @Nullable android.service.carrier.CarrierIdentifier); field public static final String CARRIER_SERVICE_INTERFACE = "android.service.carrier.CarrierService"; } diff --git a/telephony/java/android/service/carrier/CarrierService.java b/telephony/java/android/service/carrier/CarrierService.java index d06ec11f3e61..741efe47332e 100644 --- a/telephony/java/android/service/carrier/CarrierService.java +++ b/telephony/java/android/service/carrier/CarrierService.java @@ -15,6 +15,8 @@ package android.service.carrier; import android.annotation.CallSuper; +import android.annotation.Nullable; +import android.annotation.SuppressLint; import android.app.Service; import android.content.Context; import android.content.Intent; @@ -22,9 +24,12 @@ import android.os.Bundle; import android.os.IBinder; import android.os.PersistableBundle; import android.os.ResultReceiver; +import android.telephony.SubscriptionManager; import android.telephony.TelephonyRegistryManager; import android.util.Log; +import com.android.internal.util.ArrayUtils; + import java.io.FileDescriptor; import java.io.PrintWriter; @@ -87,7 +92,54 @@ public abstract class CarrierService extends Service { * PersistableBundle} may be overridden by the system's default configuration service. *

* - * @param id contains details about the current carrier that can be used do decide what + * @param id contains details about the current carrier that can be used to decide what + * configuration values to return. Instead of using details like MCCMNC to decide + * current carrier, it also contains subscription carrier id + * {@link android.telephony.TelephonyManager#getSimCarrierId()}, a platform-wide + * unique identifier for each carrier, CarrierConfigService can directly use carrier + * id as the key to look up the carrier info. + * @return a {@link PersistableBundle} object containing the configuration or null if default + * values should be used. + * @deprecated use {@link #onLoadConfig(int, CarrierIdentifier)} instead. + */ + @Deprecated + public abstract PersistableBundle onLoadConfig(CarrierIdentifier id); + + /** + * Override this method to set carrier configuration on the given {@code subscriptionId}. + *

+ * This method will be called by telephony services to get carrier-specific configuration + * values. The returned config will be saved by the system until, + *

    + *
  1. The carrier app package is updated, or
  2. + *
  3. The carrier app requests a reload with + * {@link android.telephony.CarrierConfigManager#notifyConfigChangedForSubId + * notifyConfigChangedForSubId}.
  4. + *
+ * This method can be called after a SIM card loads, which may be before or after boot. + *

+ *

+ * This method should not block for a long time. If expensive operations (e.g. network access) + * are required, this method can schedule the work and return null. Then, use + * {@link android.telephony.CarrierConfigManager#notifyConfigChangedForSubId + * notifyConfigChangedForSubId} to trigger a reload when the config is ready. + *

+ *

+ * Implementations should use the keys defined in {@link android.telephony.CarrierConfigManager + * CarrierConfigManager}. Any configuration values not set in the returned {@link + * PersistableBundle} may be overridden by the system's default configuration service. + *

+ *

+ * By default, this method just calls {@link #onLoadConfig(CarrierIdentifier)} with specified + * CarrierIdentifier {@code id}. Carrier app with target SDK + * {@link android.os.Build.VERSION_CODES#TIRAMISU} and above should override this method to + * load carrier configuration on the given {@code subscriptionId}. + * Note that {@link #onLoadConfig(CarrierIdentifier)} is still called prior to + * {@link android.os.Build.VERSION_CODES#TIRAMISU}. + *

+ * + * @param subscriptionId the subscription on which the carrier app should load configuration + * @param id contains details about the current carrier that can be used to decide what * configuration values to return. Instead of using details like MCCMNC to decide * current carrier, it also contains subscription carrier id * {@link android.telephony.TelephonyManager#getSimCarrierId()}, a platform-wide @@ -96,7 +148,11 @@ public abstract class CarrierService extends Service { * @return a {@link PersistableBundle} object containing the configuration or null if default * values should be used. */ - public abstract PersistableBundle onLoadConfig(CarrierIdentifier id); + @SuppressLint("NullableCollection") + @Nullable + public PersistableBundle onLoadConfig(int subscriptionId, @Nullable CarrierIdentifier id) { + return onLoadConfig(id); + } /** * Informs the system of an intentional upcoming carrier network change by @@ -149,10 +205,16 @@ public abstract class CarrierService extends Service { public static final String KEY_CONFIG_BUNDLE = "config_bundle"; @Override - public void getCarrierConfig(CarrierIdentifier id, ResultReceiver result) { + public void getCarrierConfig(int phoneId, CarrierIdentifier id, ResultReceiver result) { try { + int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; + int[] subIds = SubscriptionManager.getSubId(phoneId); + if (!ArrayUtils.isEmpty(subIds)) { + // There should be at most one active subscription mapping to the phoneId. + subId = subIds[0]; + } Bundle data = new Bundle(); - data.putParcelable(KEY_CONFIG_BUNDLE, CarrierService.this.onLoadConfig(id)); + data.putParcelable(KEY_CONFIG_BUNDLE, CarrierService.this.onLoadConfig(subId, id)); result.send(RESULT_OK, data); } catch (Exception e) { Log.e(LOG_TAG, "Error in onLoadConfig: " + e.getMessage(), e); diff --git a/telephony/java/android/service/carrier/ICarrierService.aidl b/telephony/java/android/service/carrier/ICarrierService.aidl index ac6f9614d8f5..054a280c3fe8 100644 --- a/telephony/java/android/service/carrier/ICarrierService.aidl +++ b/telephony/java/android/service/carrier/ICarrierService.aidl @@ -29,5 +29,5 @@ import android.service.carrier.CarrierIdentifier; interface ICarrierService { /** @see android.service.carrier.CarrierService#onLoadConfig */ - oneway void getCarrierConfig(in CarrierIdentifier id, in ResultReceiver result); + oneway void getCarrierConfig(in int phoneId, in CarrierIdentifier id, in ResultReceiver result); }