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

Commit 8e7e21d3 authored by Brad Ebinger's avatar Brad Ebinger
Browse files

Expose ImsResolver API that checks ImsService configurations

Exposes an ImsResolver API to check whether or not there is a
configured ImsService for the ImsFeature type requested. This
allows us to check if there is an ImsService available to service
a request from another app and if not, send a unsupported operation
ImsExcpetion.

Bug: 184188331
Test: atest CtsTelephonyTestCases FrameworksTelephonyTestCases
Change-Id: I69b7f73d35bd1bd5049ba9a437907894f22b7e0b
parent 9f4843e4
Loading
Loading
Loading
Loading
+48 −20
Original line number Diff line number Diff line
@@ -430,8 +430,8 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
    // should only be accessed from handler
    private SparseArray<Map<Integer, String>> mCarrierServices;
    // Package name of the default device services, Maps ImsFeature -> packageName.
    // should only be accessed from handler
    private Map<Integer, String> mDeviceServices;
    // Must synchronize on this object to access.
    private final Map<Integer, String> mDeviceServices = new ArrayMap<>();
    // Persistent Logging
    private final LocalLog mEventLog = new LocalLog(50);

@@ -564,7 +564,6 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
        mReceiverContext = context.createContextAsUser(UserHandle.ALL, 0 /*flags*/);

        mCarrierServices = new SparseArray<>(mNumSlots);
        mDeviceServices = new ArrayMap<>();
        setDeviceConfiguration(defaultMmTelPackageName, ImsFeature.FEATURE_EMERGENCY_MMTEL);
        setDeviceConfiguration(defaultMmTelPackageName, ImsFeature.FEATURE_MMTEL);
        setDeviceConfiguration(defaultRcsPackageName, ImsFeature.FEATURE_RCS);
@@ -778,15 +777,17 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
        return true;
    }

    // not synchronized, access through handler ONLY.
    private String getDeviceConfiguration(@ImsFeature.FeatureType int featureType) {
        synchronized (mDeviceServices) {
            return mDeviceServices.getOrDefault(featureType, "");
        }
    }

    // not synchronized, access in handler ONLY.
    private void setDeviceConfiguration(String name, @ImsFeature.FeatureType int featureType) {
        synchronized (mDeviceServices) {
            mDeviceServices.put(featureType, name);
        }
    }

    // not synchronized, access in handler ONLY.
    private void setCarrierConfiguredPackageName(@NonNull String packageName, int slotId,
@@ -891,6 +892,26 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
            return null;
        }
    }

    /**
     * Determines if there is a valid ImsService configured for the specified ImsFeature.
     * @param slotId The slot ID to check for.
     * @param featureType The ImsFeature featureType to check for.
     * @return true if there is an ImsService configured for the specified ImsFeature type, false
     * if there is not.
     */
    public boolean isImsServiceConfiguredForFeature(int slotId,
            @ImsFeature.FeatureType int featureType) {
        if (!TextUtils.isEmpty(getDeviceConfiguration(featureType))) {
            // Shortcut a little bit here - instead of dynamically looking up the configured
            // package name, which can be a long operation depending on the state, just return true
            // if there is a configured device ImsService for the requested feature because that
            // means there will always be at least a device configured ImsService.
            return true;
        }
        return !TextUtils.isEmpty(getConfiguredImsServicePackageName(slotId, featureType));
    }

    /**
     * Resolves the PackageName of the ImsService that is configured to be bound for the slotId and
     * FeatureType specified and returns it.
@@ -913,16 +934,13 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
            return null;
        }
        CompletableFuture<String> packageNameFuture = new CompletableFuture<>();
        final long startTimeMs = System.currentTimeMillis();
        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,
@@ -936,12 +954,18 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
        }
        try {
            String packageName = packageNameFuture.get();
            long timeDiff = System.currentTimeMillis() - startTimeMs;
            if (timeDiff > 50) {
                // Took an unusually long amount of time (> 50 ms), so log it.
                mEventLog.log("getResolvedImsServicePackageName - [" + slotId + ", "
                        + ImsFeature.FEATURE_LOG_MAP.get(featureType)
                    + "], async query complete with package name: " + packageName);
            Log.d(TAG, "getResolvedImsServicePackageName: [" + slotId + ", "
                        + "], async query complete, took " + timeDiff + " ms with package name: "
                        + packageName);
                Log.w(TAG, "getResolvedImsServicePackageName: [" + slotId + ", "
                        + ImsFeature.FEATURE_LOG_MAP.get(featureType)
                    + "], async query complete with package name: " + packageName);
                        + "], async query complete, took " + timeDiff + " ms with package name: "
                        + packageName);
            }
            return packageName;
        } catch (Exception e) {
            mEventLog.log("getResolvedImsServicePackageName - [" + slotId + ", "
@@ -1093,8 +1117,10 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal

    private boolean isDeviceService(ImsServiceInfo info) {
        if (info == null) return false;
        synchronized (mDeviceServices) {
            return mDeviceServices.containsValue(info.name.getPackageName());
        }
    }

    private List<Integer> getSlotsForActiveCarrierService(ImsServiceInfo info) {
        if (info == null) return Collections.emptyList();
@@ -1711,9 +1737,11 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
        pw.increaseIndent();
        pw.println("Device:");
        pw.increaseIndent();
        synchronized (mDeviceServices) {
            for (Integer i : mDeviceServices.keySet()) {
                pw.println(ImsFeature.FEATURE_LOG_MAP.get(i) + " -> " + mDeviceServices.get(i));
            }
        }
        pw.decreaseIndent();
        pw.println("Carrier: ");
        pw.increaseIndent();
+35 −2
Original line number Diff line number Diff line
@@ -193,6 +193,39 @@ public class ImsResolverTest extends ImsTestBase {
        assertFalse(testCachedService.featureFromMetadata);
    }

    /**
     * Add a device ImsService and ensure that querying ImsResolver to see if an ImsService is
     * configured succeeds.
     */
    @Test
    @SmallTest
    public void testIsDeviceImsServiceConfigured() throws Exception {
        setupResolver(1 /*numSlots*/, TEST_DEVICE_DEFAULT_NAME.getPackageName(),
                TEST_DEVICE_DEFAULT_NAME.getPackageName());
        HashSet<String> features = new HashSet<>();
        features.add(ImsResolver.METADATA_EMERGENCY_MMTEL_FEATURE);
        features.add(ImsResolver.METADATA_MMTEL_FEATURE);
        features.add(ImsResolver.METADATA_RCS_FEATURE);
        setupPackageQuery(TEST_DEVICE_DEFAULT_NAME, features, true);
        setupController();

        // Complete package manager lookup and cache.
        startBindCarrierConfigAlreadySet();

        // device package name should be returned for both features.
        final Boolean[] isConfigured = new Boolean[1];
        // Calling this method will block us until the looper processes the command, so use
        // runWithLooper to allow the message to be processed.
        mLooper.runWithLooper(() ->
                isConfigured[0] = mTestImsResolver.isImsServiceConfiguredForFeature(0,
                        ImsFeature.FEATURE_MMTEL));
        assertTrue(isConfigured[0]);
        mLooper.runWithLooper(() ->
                isConfigured[0] = mTestImsResolver.isImsServiceConfiguredForFeature(0,
                        ImsFeature.FEATURE_RCS));
        assertTrue(isConfigured[0]);
    }

    /**
     * Add a device ImsService and ensure that querying the configured ImsService for all features
     * reports the device ImsService.
@@ -227,7 +260,7 @@ public class ImsResolverTest extends ImsTestBase {
    }

    /**
     * Add in the case that there is no device or carrier ImsService found, we return null for
     * In the case that there is no device or carrier ImsService found, we return null for
     * configuration queries.
     */
    @Test
@@ -255,7 +288,7 @@ public class ImsResolverTest extends ImsTestBase {
    }

    /**
     * Add in the case that there is no device or carrier ImsService configured, we return null for
     * In the case that there is no device or carrier ImsService configured, we return null for
     * configuration queries.
     */
    @Test