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

Commit 843ddc54 authored by Brad Ebinger's avatar Brad Ebinger Committed by Android (Google) Code Review
Browse files

Merge "Allow device ImsService implementing RCS to use CarrierMessagingService" into sc-dev

parents 6c953b47 cbc2add8
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -102,7 +102,8 @@ public class CarrierServicesSmsFilter {
    }

    /**
     * @return {@code true} if the SMS was handled by carrier services.
     * @return {@code true} if the SMS was handled by a carrier application or an ImsService
     * implementing RCS features.
     */
    @VisibleForTesting
    public boolean filter() {
@@ -111,10 +112,10 @@ public class CarrierServicesSmsFilter {
        if (carrierAppForFiltering.isPresent()) {
            smsFilterPackages.add(carrierAppForFiltering.get());
        }
        String carrierImsPackage = CarrierSmsUtils.getCarrierImsPackageForIntent(mContext, mPhone,
        String imsRcsPackage = CarrierSmsUtils.getImsRcsPackageForIntent(mContext, mPhone,
                new Intent(CarrierMessagingService.SERVICE_INTERFACE));
        if (carrierImsPackage != null) {
            smsFilterPackages.add(carrierImsPackage);
        if (imsRcsPackage != null) {
            smsFilterPackages.add(imsRcsPackage);
        }

        if (mFilterAggregator != null) {
+18 −22
Original line number Diff line number Diff line
@@ -22,9 +22,9 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Binder;
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
import android.telephony.ims.feature.ImsFeature;

import com.android.internal.telephony.ims.ImsResolver;
import com.android.telephony.Rlog;

import java.util.List;
@@ -36,23 +36,20 @@ public class CarrierSmsUtils {
    protected static final boolean VDBG = false;
    protected static final String TAG = CarrierSmsUtils.class.getSimpleName();

    private static final String CARRIER_IMS_PACKAGE_KEY =
            CarrierConfigManager.KEY_CONFIG_IMS_PACKAGE_OVERRIDE_STRING;

    /** Return a Carrier-overridden IMS package, if it exists and is a CarrierSmsFilter
     *
    /**
     * Return the package name of the ImsService that is implementing RCS features for the device.
     * @param context calling context
     * @param phone object from telephony
     * @param intent that should match a CarrierSmsFilter
     * @return the name of the IMS CarrierService package
     * @return the name of the ImsService implementing RCS features on the device.
     */
    @Nullable
    public static String getCarrierImsPackageForIntent(
    public static String getImsRcsPackageForIntent(
            Context context, Phone phone, Intent intent) {

        String carrierImsPackage = getCarrierImsPackage(context, phone);
        String carrierImsPackage = getImsRcsPackage(phone);
        if (carrierImsPackage == null) {
            if (VDBG) Rlog.v(TAG, "No CarrierImsPackage override found");
            if (VDBG) Rlog.v(TAG, "No ImsService found implementing RCS.");
            return null;
        }

@@ -71,23 +68,22 @@ public class CarrierSmsUtils {
        return null;
    }

    /**
     * @return the package name of the ImsService that is configured to implement RCS, or null if
     * there is none configured/available.
     */
    @Nullable
    private static String getCarrierImsPackage(Context context, Phone phone) {
        CarrierConfigManager cm = (CarrierConfigManager) context.getSystemService(
                Context.CARRIER_CONFIG_SERVICE);
        if (cm == null) {
            Rlog.e(TAG, "Failed to retrieve CarrierConfigManager");
    private static String getImsRcsPackage(Phone phone) {
        ImsResolver resolver = ImsResolver.getInstance();
        if (resolver == null) {
            Rlog.i(TAG, "getImsRcsPackage: Device does not support IMS - skipping");
            return null;
        }

        final long identity = Binder.clearCallingIdentity();
        try {
            PersistableBundle config = cm.getConfigForSubId(phone.getSubId());
            if (config == null) {
                if (VDBG) Rlog.v(TAG, "No CarrierConfig for subId:" + phone.getSubId());
                return null;
            }
            return config.getString(CARRIER_IMS_PACKAGE_KEY, null);
            return resolver.getConfiguredImsServicePackageName(phone.getPhoneId(),
                    ImsFeature.FEATURE_RCS);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
+3 −3
Original line number Diff line number Diff line
@@ -2516,9 +2516,9 @@ public abstract class SMSDispatcher extends Handler {
        if (carrierPackages != null && carrierPackages.size() == 1) {
            return carrierPackages.get(0);
        }
        // If there is no carrier package which implements CarrierMessagingService, then lookup if
        // for a carrierImsPackage that implements CarrierMessagingService.
        return CarrierSmsUtils.getCarrierImsPackageForIntent(mContext, mPhone,
        // If there is no carrier package which implements CarrierMessagingService, then lookup
        // an ImsService implementing RCS that also implements CarrierMessagingService.
        return CarrierSmsUtils.getImsRcsPackageForIntent(mContext, mPhone,
                new Intent(CarrierMessagingService.SERVICE_INTERFACE));
    }

+3 −3
Original line number Diff line number Diff line
@@ -78,14 +78,14 @@ public class SmsPermissions {
    /**
     * Enforces that the caller is one of the following apps:
     * <ul>
     *     <li> IMS App
     *     <li> IMS App determined by telephony to implement RCS features
     *     <li> Carrier App
     * </ul>
     */
    public void enforceCallerIsImsAppOrCarrierApp(String message) {
        String carrierImsPackage = CarrierSmsUtils.getCarrierImsPackageForIntent(mContext,
        String imsRcsPackage = CarrierSmsUtils.getImsRcsPackageForIntent(mContext,
                mPhone, new Intent(CarrierMessagingService.SERVICE_INTERFACE));
        if (carrierImsPackage != null && packageNameMatchesCallingUid(carrierImsPackage)) {
        if (imsRcsPackage != null && packageNameMatchesCallingUid(imsRcsPackage)) {
            return;
        }
        TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
+122 −1
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@@ -128,6 +129,27 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
    // Delay between dynamic ImsService queries.
    private static final int DELAY_DYNAMIC_QUERY_MS = 5000;

    private static ImsResolver sInstance;

    /**
     * Create the ImsResolver Service singleton instance.
     */
    public static void make(Context context, String defaultMmTelPackageName,
            String defaultRcsPackageName, int numSlots, ImsFeatureBinderRepository repo) {
        if (sInstance == null) {
            sInstance = new ImsResolver(context, defaultMmTelPackageName, defaultRcsPackageName,
                    numSlots, repo);
        }
    }

    /**
     * @return The ImsResolver Service instance. May be {@code null} if no ImsResolver was created
     * due to IMS not being supported.
     */
    public static @Nullable ImsResolver getInstance() {
        return sInstance;
    }

    private static class OverrideConfig {
        public final int slotId;
        public final boolean isCarrierService;
@@ -830,7 +852,18 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
            return false;
        }
        // Config exists, but the carrier ImsService also needs to support this feature
        ImsServiceInfo info = getImsServiceInfoFromCache(carrierPackage);
        return doesCachedImsServiceExist(carrierPackage, slotId, featureType);
    }

    /**
     * Check the cached ImsServices that exist on this device to determine if there is a ImsService
     * with the same package name that matches the provided configuration.
     */
    // not synchronized, access in handler ONLY.
    private boolean doesCachedImsServiceExist(String packageName, int slotId,
            @ImsFeature.FeatureType int featureType) {
        // Config exists, but the carrier ImsService also needs to support this feature
        ImsServiceInfo info = getImsServiceInfoFromCache(packageName);
        return info != null && info.getSupportedFeatures().stream().anyMatch(
                feature -> feature.slotId == slotId && feature.featureType == featureType);
    }
@@ -858,6 +891,94 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
            return null;
        }
    }
    /**
     * Resolves the PackageName of the ImsService that is configured to be bound for the slotId and
     * FeatureType specified and returns it.
     * <p>
     * If there is a PackageName that is configured, but there is no application on the device that
     * fulfills that configuration, this method will also return {@code null} as the ImsService will
     * not be bound.
     *
     * @param slotId The slot ID that the request is for.
     * @param featureType The ImsService feature type that the request is for.
     * @return The package name of the ImsService that will be bound from telephony for the provided
     * slot id and featureType.
     */
    public String getConfiguredImsServicePackageName(int slotId,
            @ImsFeature.FeatureType int featureType) {
        if (slotId < 0 || slotId >= mNumSlots || featureType <= ImsFeature.FEATURE_INVALID
                || featureType >= ImsFeature.FEATURE_MAX) {
            Log.w(TAG, "getResolvedImsServicePackageName received invalid parameters - slot: "
                    + slotId + ", feature: " + featureType);
            return null;
        }
        CompletableFuture<String> packageNameFuture = new CompletableFuture<>();
        if (mHandler.getLooper().isCurrentThread()) {
            // If we are on the same thread as the Handler's looper, run the internal method
            // directly.
            packageNameFuture.complete(getConfiguredImsServicePackageNameInternal(slotId,
                    featureType));
        } else {
            mEventLog.log("getResolvedImsServicePackageName - [" + slotId + ", "
                    + ImsFeature.FEATURE_LOG_MAP.get(featureType) + "], starting query...");
            Log.d(TAG, "getResolvedImsServicePackageName: [" + slotId + ", "
                    + ImsFeature.FEATURE_LOG_MAP.get(featureType) + "], starting query...");
            mHandler.post(() -> {
                try {
                    packageNameFuture.complete(getConfiguredImsServicePackageNameInternal(slotId,
                            featureType));
                } catch (Exception e) {
                    // Catch all Exceptions to ensure we do not block indefinitely in the case of an
                    // unexpected error.
                    packageNameFuture.completeExceptionally(e);
                }
            });
        }
        try {
            String packageName = packageNameFuture.get();
            mEventLog.log("getResolvedImsServicePackageName - [" + slotId + ", "
                    + ImsFeature.FEATURE_LOG_MAP.get(featureType)
                    + "], async query complete with package name: " + packageName);
            Log.d(TAG, "getResolvedImsServicePackageName: [" + slotId + ", "
                    + ImsFeature.FEATURE_LOG_MAP.get(featureType)
                    + "], async query complete with package name: " + packageName);
            return packageName;
        } catch (Exception e) {
            mEventLog.log("getResolvedImsServicePackageName - [" + slotId + ", "
                    + ImsFeature.FEATURE_LOG_MAP.get(featureType) + "] -> Exception: " + e);
            Log.w(TAG, "getResolvedImsServicePackageName: [" + slotId + ", "
                    + ImsFeature.FEATURE_LOG_MAP.get(featureType) + "] returned Exception: " + e);
            return null;
        }
    }

    /**
     * @return the package name for the configured carrier ImsService if it exists on the device and
     * supports the supplied slotId and featureType. If no such configuration exists, fall back to
     * the device ImsService. If neither exist, then return {@code null};
     */
    // Not synchronized, access on Handler ONLY!
    private String getConfiguredImsServicePackageNameInternal(int slotId,
            @ImsFeature.FeatureType int featureType) {
        // If a carrier ImsService is configured to be used for the provided slotId and
        // featureType, then return that one.
        String carrierPackage = getCarrierConfiguredPackageName(slotId, featureType);
        if (!TextUtils.isEmpty(carrierPackage)
                && doesCachedImsServiceExist(carrierPackage, slotId, featureType)) {
            return carrierPackage;
        }
        // If there is no carrier ImsService configured for that configuration, then
        // return the device's default ImsService for the provided slotId and
        // featureType.
        String devicePackage = getDeviceConfiguration(featureType);
        if (!TextUtils.isEmpty(devicePackage)
                && doesCachedImsServiceExist(devicePackage, slotId, featureType)) {
            return devicePackage;
        }
        // There is no ImsService configuration that exists for the slotId and
        // featureType.
        return null;
    }

    private void putImsController(int slotId, int feature, ImsServiceController controller) {
        if (slotId < 0 || slotId >= mNumSlots || feature <= ImsFeature.FEATURE_INVALID
Loading