Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f94d838d authored by rambowang's avatar rambowang
Browse files

Introduce APIs to retrieve only carrier configs as needed

Current CarrierConfigManager APIs only allow to retrieve
ALL supported carrier configs at once. It may be as many
as hundreds of keys/values in one bundle which is not only
slow but also consumes unnecessarily more resources.

Clients study shows that the majority of the clients actually
only care about one or few of carrier configs.

The new APIs allow clients to specify a single or
multiple configs they care about. The performance profiling
shows that it is not only much faster but also consumes much
less resources.

Bug: 244087782
Test: atest CarrierConfigManagerTest
Change-Id: I436b9ad1d7e928d628c0103144cd345e8c4c4e3c
Merged-In: I436b9ad1d7e928d628c0103144cd345e8c4c4e3c
(cherry picked from commit 365825e2)
parent 08f7735f
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -41269,9 +41269,11 @@ package android.telephony {
  }
  public class CarrierConfigManager {
    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public android.os.PersistableBundle getConfig();
    method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public android.os.PersistableBundle getConfig();
    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.READ_PHONE_STATE, "carrier privileges"}) public android.os.PersistableBundle getConfig(@NonNull java.lang.String...);
    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public android.os.PersistableBundle getConfigByComponentForSubId(@NonNull String, int);
    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public android.os.PersistableBundle getConfigForSubId(int);
    method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public android.os.PersistableBundle getConfigForSubId(int);
    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.READ_PHONE_STATE, "carrier privileges"}) public android.os.PersistableBundle getConfigForSubId(int, @NonNull java.lang.String...);
    method public static boolean isConfigForIdentifiedCarrier(android.os.PersistableBundle);
    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyConfigChangedForSubId(int);
    field public static final String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
+91 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import com.android.internal.telephony.ICarrierConfigLoader;
import com.android.telephony.Rlog;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
@@ -9335,10 +9336,13 @@ public class CarrierConfigManager {
     * @param subId the subscription ID, normally obtained from {@link SubscriptionManager}.
     * @return A {@link PersistableBundle} containing the config for the given subId, or default
     *         values for an invalid subId.
     *
     * @deprecated Use {@link #getConfigForSubId(int, String...)} instead.
     */
    @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
    @Nullable
    @Deprecated
    public PersistableBundle getConfigForSubId(int subId) {
        try {
            ICarrierConfigLoader loader = getICarrierConfigLoader();
@@ -9356,6 +9360,58 @@ public class CarrierConfigManager {
        return null;
    }

    /**
     * Gets the configuration values of the specified keys for a particular subscription.
     *
     * <p>If an invalid subId is used, the returned configuration will contain default values for
     * the specified keys.
     *
     * <p>After using this method to get the configuration bundle,
     * {@link #isConfigForIdentifiedCarrier(PersistableBundle)} should be called to confirm whether
     * any carrier specific configuration has been applied.
     *
     * <p>Note that on success, the key/value for {@link #KEY_CARRIER_CONFIG_VERSION_STRING} and
     * {@link #KEY_CARRIER_CONFIG_APPLIED_BOOL} are always in the returned bundle, no matter if they
     * were explicitly requested.
     *
     * <p>Requires Permission:
     * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}, or the calling app
     * has carrier privileges on the specified subscription (see
     * {@link TelephonyManager#hasCarrierPrivileges()}).
     *
     * @param subId The subscription ID on which the carrier config should be retrieved.
     * @param keys  The carrier config keys to retrieve values.
     * @return A {@link PersistableBundle} with key/value mapping for the specified configuration
     * on success, or an empty (but never null) bundle on failure (for example, when no value for
     * the specified key can be found).
     */
    @RequiresPermission(anyOf = {
            Manifest.permission.READ_PHONE_STATE,
            "carrier privileges",
    })
    @NonNull
    public PersistableBundle getConfigForSubId(int subId, @NonNull String... keys) {
        Objects.requireNonNull(keys, "Config keys should be non-null");
        for (String key : keys) {
            Objects.requireNonNull(key, "Config key should be non-null");
        }

        try {
            ICarrierConfigLoader loader = getICarrierConfigLoader();
            if (loader == null) {
                Rlog.w(TAG, "Error getting config for subId " + subId
                        + " ICarrierConfigLoader is null");
                throw new IllegalStateException("Carrier config loader is not available.");
            }
            return loader.getConfigSubsetForSubIdWithFeature(subId, mContext.getOpPackageName(),
                    mContext.getAttributionTag(), keys);
        } catch (RemoteException ex) {
            Rlog.e(TAG, "Error getting config for subId " + subId + ": " + ex);
            ex.rethrowAsRuntimeException();
        }
        return new PersistableBundle();
    }

    /**
     * Overrides the carrier config of the provided subscription ID with the provided values.
     *
@@ -9430,14 +9486,49 @@ public class CarrierConfigManager {
     * has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges()}).
     *
     * @see #getConfigForSubId
     * @see #getConfig(String...)
     * @deprecated use {@link #getConfig(String...)} instead.
     */
    @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
    @Nullable
    @Deprecated
    public PersistableBundle getConfig() {
        return getConfigForSubId(SubscriptionManager.getDefaultSubscriptionId());
    }

    /**
     * Gets the configuration values of the specified config keys applied for the default
     * subscription.
     *
     * <p>After using this method to get the configuration bundle, {@link
     * #isConfigForIdentifiedCarrier(PersistableBundle)} should be called to confirm whether any
     * carrier specific configuration has been applied.
     *
     * <p>Note that on success, the key/value for {@link #KEY_CARRIER_CONFIG_VERSION_STRING} and
     * {@link #KEY_CARRIER_CONFIG_APPLIED_BOOL} are always in the returned bundle, no matter if
     * they were explicitly requested.
     *
     * <p>Requires Permission:
     * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}, or the calling app
     * has carrier privileges for the default subscription (see
     * {@link TelephonyManager#hasCarrierPrivileges()}).
     *
     * @param keys The config keys to retrieve values
     * @return A {@link PersistableBundle} with key/value mapping for the specified carrier
     * configs on success, or an empty (but never null) bundle on failure.
     * @see #getConfigForSubId(int, String...)
     * @see SubscriptionManager#getDefaultSubscriptionId()
     */
    @RequiresPermission(anyOf = {
            Manifest.permission.READ_PHONE_STATE,
            "carrier privileges",
    })
    @NonNull
    public PersistableBundle getConfig(@NonNull String... keys) {
        return getConfigForSubId(SubscriptionManager.getDefaultSubscriptionId(), keys);
    }

    /**
     * Determines whether a configuration {@link PersistableBundle} obtained from
     * {@link #getConfig()} or {@link #getConfigForSubId(int)} corresponds to an identified carrier.
+2 −0
Original line number Diff line number Diff line
@@ -38,4 +38,6 @@ interface ICarrierConfigLoader {

    String getDefaultCarrierServicePackageName();

    PersistableBundle getConfigSubsetForSubIdWithFeature(int subId, String callingPackage,
                String callingFeatureId, in String[] carrierConfigs);
}