Loading src/java/com/android/internal/telephony/ims/ImsResolver.java +48 −20 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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, Loading Loading @@ -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. Loading @@ -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, Loading @@ -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 + ", " Loading Loading @@ -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(); Loading Loading @@ -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(); Loading tests/telephonytests/src/com/android/internal/telephony/ims/ImsResolverTest.java +35 −2 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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 Loading Loading @@ -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 Loading Loading
src/java/com/android/internal/telephony/ims/ImsResolver.java +48 −20 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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, Loading Loading @@ -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. Loading @@ -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, Loading @@ -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 + ", " Loading Loading @@ -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(); Loading Loading @@ -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(); Loading
tests/telephonytests/src/com/android/internal/telephony/ims/ImsResolverTest.java +35 −2 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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 Loading Loading @@ -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 Loading