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

Commit 1468bc2f authored by Brad Ebinger's avatar Brad Ebinger Committed by Gerrit Code Review
Browse files

Merge "When BOOT_COMPLETE occurs, recalculate ImsServices"

parents 658349ea 9a4a11e1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -243,7 +243,7 @@ public class PhoneFactory {
                    Rlog.i(LOG_TAG, "ImsResolver: defaultImsPackage: " + defaultImsPackage);
                    sImsResolver = new ImsResolver(sContext, defaultImsPackage, numPhones,
                            isDynamicBinding);
                    sImsResolver.initPopulateCacheAndStartBind();
                    sImsResolver.initialize();
                    // Start monitoring after defaults have been made.
                    // Default phone must be ready before ImsPhone is created because ImsService
                    // might need it when it is being opened. This should initialize multiple
+53 −21
Original line number Diff line number Diff line
@@ -97,6 +97,9 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
    private static final int HANDLER_DYNAMIC_FEATURE_CHANGE = 4;
    // Testing: Overrides the current configuration for ImsService binding
    private static final int HANDLER_OVERRIDE_IMS_SERVICE_CONFIG = 5;
    // Based on boot complete indication. When this happens, there may be ImsServices that are not
    // direct boot aware that need to be started.
    private static final int HANDLER_BOOT_COMPLETE = 6;

    // Delay between dynamic ImsService queries.
    private static final int DELAY_DYNAMIC_QUERY_MS = 5000;
@@ -173,7 +176,7 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
                res.append("(");
                res.append(feature.slotId);
                res.append(",");
                res.append(feature.featureType);
                res.append(ImsFeature.FEATURE_LOG_MAP.get(feature.featureType));
                res.append(") ");
            }
            return res.toString();
@@ -224,6 +227,18 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
        }
    };

    // Receives the broadcast that the device has finished booting (and the device is no longer
    // encrypted).
    private BroadcastReceiver mBootCompleted = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.i(TAG, "Received BOOT_COMPLETED");
            // Recalculate all cached services to pick up ones that have just been enabled since
            // boot complete.
            mHandler.obtainMessage(HANDLER_BOOT_COMPLETE, null).sendToTarget();
        }
    };

    /**
     * Testing interface used to mock SubscriptionManager in testing
     */
@@ -352,6 +367,11 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
                maybeRemovedImsService(packageName);
                break;
            }
            case HANDLER_BOOT_COMPLETE: {
                // Re-evaluate bound services for all slots after requerying packagemanager
                maybeAddedImsService(null);
                break;
            }
            case HANDLER_CONFIG_CHANGED: {
                int slotId = (Integer) msg.obj;
                carrierConfigChanged(slotId);
@@ -379,7 +399,7 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
                if (isCarrierImsService) {
                    Log.i(TAG, "overriding carrier ImsService - slot=" + slotId + " packageName="
                            + packageName);
                    maybeRebindService(slotId, packageName);
                    overrideService(slotId, packageName);
                } else {
                    Log.i(TAG, "overriding device ImsService -  packageName=" + packageName);
                    if (TextUtils.equals(mDeviceService, packageName)) {
@@ -417,8 +437,7 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
                @Override
                public void onComplete(ComponentName name,
                        Set<ImsFeatureConfiguration.FeatureSlotPair> features) {
                    Log.d(TAG, "onComplete called for name: " + name + "features:"
                            + printFeatures(features));
                    Log.d(TAG, "onComplete called for name: " + name + printFeatures(features));
                    handleFeaturesChanged(name, features);
                }

@@ -472,6 +491,8 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal

            context.registerReceiver(mConfigChangedReceiver, new IntentFilter(
                    CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
            context.registerReceiver(mBootCompleted, new IntentFilter(
                    Intent.ACTION_BOOT_COMPLETED));
        }
    }

@@ -496,10 +517,9 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
    }

    /**
     * Needs to be called after the constructor to first populate the cache and possibly bind to
     * ImsServices.
     * Needs to be called after the constructor to kick off the process of binding to ImsServices.
     */
    public void initPopulateCacheAndStartBind() {
    public void initialize() {
        Log.i(TAG, "Initializing cache and binding.");
        mFeatureQueryManager = mDynamicQueryManagerFactory.create(mContext, mDynamicQueryListener);
        // Populates the CarrierConfig override package names for each slot
@@ -678,7 +698,8 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
                mBoundImsServicesByFeature.add(slotId, services);
            }
            Log.i(TAG, "ImsServiceController added on slot: " + slotId + " with feature: "
                    + feature + " using package: " + controller.getComponentName());
                    + ImsFeature.FEATURE_LOG_MAP.get(feature) + " using package: "
                    + controller.getComponentName());
            services.put(feature, controller);
        }
    }
@@ -698,7 +719,8 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
            ImsServiceController c = services.get(feature, null);
            if (c != null) {
                Log.i(TAG, "ImsServiceController removed on slot: " + slotId + " with feature: "
                        + feature + " using package: " + c.getComponentName());
                        + ImsFeature.FEATURE_LOG_MAP.get(feature) + " using package: "
                        + c.getComponentName());
                services.remove(feature);
            }
            return c;
@@ -999,10 +1021,9 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
        return bindableFeatures > 0;
    }

    // Possibly rebind to another ImsService if currently installed ImsServices were changed or if
    // the SIM card has changed.
    // Possibly rebind to another ImsService for testing.
    // Called from the handler ONLY
    private void maybeRebindService(int slotId, String newPackageName) {
    private void overrideService(int slotId, String newPackageName) {
        if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
            // not specified, replace package on all slots.
            for (int i = 0; i < mNumSlots; i++) {
@@ -1014,18 +1035,29 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal

    }

    // Called from handler ONLY.
    private void carrierConfigChanged(int slotId) {
        if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
            // not specified, update carrier override cache and possibly rebind on all slots.
            for (int i = 0; i < mNumSlots; i++) {
                updateBoundCarrierServices(i, getImsPackageOverrideConfig(i));
            }
        }
        updateBoundCarrierServices(slotId, getImsPackageOverrideConfig(slotId));
    }

    private String getImsPackageOverrideConfig(int slotId) {
        int subId = mSubscriptionManagerProxy.getSubId(slotId);
        PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
        if (config != null) {
            String newPackageName = config.getString(
                    CarrierConfigManager.KEY_CONFIG_IMS_PACKAGE_OVERRIDE_STRING, null);
            maybeRebindService(slotId, newPackageName);
        } else {
            Log.w(TAG, "carrierConfigChanged: CarrierConfig is null!");
        }
        if (config == null) return null;
        return config.getString(CarrierConfigManager.KEY_CONFIG_IMS_PACKAGE_OVERRIDE_STRING, null);
    }

    /**
     * Use the slotId specified to update the carrier override cache with the new package name.
     * If it has changed, trigger an unbind from the old service kick off the process to recalculate
     * features supported on the new service.
     */
    private void updateBoundCarrierServices(int slotId, String newPackageName) {
        if (slotId > SubscriptionManager.INVALID_SIM_SLOT_INDEX && slotId < mNumSlots) {
            String oldPackageName = mCarrierServices[slotId];
@@ -1142,7 +1174,7 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
                featureString.append("{");
                featureString.append(feature.slotId);
                featureString.append(",");
                featureString.append(feature.featureType);
                featureString.append(ImsFeature.FEATURE_LOG_MAP.get(feature.featureType));
                featureString.append("} ");
            }
            featureString.append("]");
+4 −2
Original line number Diff line number Diff line
@@ -246,7 +246,8 @@ public class ImsServiceController {
            @Override
            public void notifyImsFeatureStatus(int featureStatus) throws RemoteException {
                Log.i(LOG_TAG, "notifyImsFeatureStatus: slot=" + mSlotId + ", feature="
                        + mFeatureType + ", status=" + featureStatus);
                        + ImsFeature.FEATURE_LOG_MAP.get(mFeatureType) + ", status="
                        + ImsFeature.STATE_LOG_MAP.get(featureStatus));
                sendImsFeatureStatusChanged(mSlotId, mFeatureType, featureStatus);
            }
        };
@@ -692,7 +693,8 @@ public class ImsServiceController {
            } catch (RemoteException e) {
                // The connection to this ImsService doesn't exist. This may happen if the service
                // has died and we are removing features.
                Log.i(LOG_TAG, "Couldn't remove feature {" + featurePair.featureType
                Log.i(LOG_TAG, "Couldn't remove feature {"
                        + ImsFeature.FEATURE_LOG_MAP.get(featurePair.featureType)
                        + "}, connection is down: " + e.getMessage());
            }
        } else {
+52 −6
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@@ -58,7 +59,6 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;

import java.util.ArrayList;
import java.util.HashSet;
@@ -96,6 +96,7 @@ public class ImsResolverTest extends ImsTestBase {
    private ImsResolver mTestImsResolver;
    private BroadcastReceiver mTestPackageBroadcastReceiver;
    private BroadcastReceiver mTestCarrierConfigReceiver;
    private BroadcastReceiver mTestBootCompleteReceiver;
    private ImsServiceFeatureQueryManager.Listener mDynamicQueryListener;
    private PersistableBundle[] mCarrierConfigs;

@@ -793,6 +794,50 @@ public class ImsResolverTest extends ImsTestBase {
        verify(deviceController).changeImsServiceFeatures(deviceFeatureSet);
    }

    /**
     * Inform the ImsResolver that BOOT_COMPLETE has happened. A non-FBE enabled ImsService is now
     * available to be bound.
     */
    @Test
    @SmallTest
    public void testBootCompleteNonFbeEnabledCarrierImsService() throws RemoteException {
        setupResolver(2/*numSlots*/);
        List<ResolveInfo> info = new ArrayList<>();
        Set<String> deviceFeatures = new HashSet<>();
        deviceFeatures.add(ImsResolver.METADATA_MMTEL_FEATURE);
        deviceFeatures.add(ImsResolver.METADATA_RCS_FEATURE);
        // Set the carrier override package for slot 0
        setConfigCarrierString(0, TEST_CARRIER_DEFAULT_NAME.getPackageName());
        // Use device default package, which will load the ImsService that the device provides
        info.add(getResolveInfo(TEST_DEVICE_DEFAULT_NAME, deviceFeatures, true));
        setupPackageQuery(info);
        ImsServiceController deviceController = mock(ImsServiceController.class);
        ImsServiceController carrierController = mock(ImsServiceController.class);
        setImsServiceControllerFactory(deviceController, carrierController);

        // Bind with device ImsService
        startBind();

        // Boot complete happens and the Carrier ImsService is now available.
        HashSet<ImsFeatureConfiguration.FeatureSlotPair> carrierFeatures = new HashSet<>();
        // Carrier service doesn't support the voice feature.
        carrierFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(0, ImsFeature.FEATURE_RCS));
        info.add(getResolveInfo(TEST_CARRIER_DEFAULT_NAME, new HashSet<>(), true));
        // Boot complete has happened and the carrier ImsService is now available.
        mTestBootCompleteReceiver.onReceive(null, new Intent(Intent.ACTION_BOOT_COMPLETED));
        waitForHandlerAction(mTestImsResolver.getHandler(), TEST_TIMEOUT);
        setupDynamicQueryFeatures(TEST_CARRIER_DEFAULT_NAME, carrierFeatures, 1);

        // Verify that all features that have been defined for the carrier override are bound
        verify(carrierController).bind(carrierFeatures);
        // device features change
        HashSet<ImsFeatureConfiguration.FeatureSlotPair> deviceFeatureSet =
                convertToHashSet(deviceFeatures, 1);
        deviceFeatureSet.addAll(convertToHashSet(deviceFeatures, 0));
        deviceFeatureSet.removeAll(carrierFeatures);
        verify(deviceController).changeImsServiceFeatures(deviceFeatureSet);
    }

    private void setupResolver(int numSlots) {
        when(mMockContext.getSystemService(eq(Context.CARRIER_CONFIG_SERVICE))).thenReturn(
                mMockCarrierConfigManager);
@@ -811,13 +856,14 @@ public class ImsResolverTest extends ImsTestBase {

        ArgumentCaptor<BroadcastReceiver> packageBroadcastCaptor =
                ArgumentCaptor.forClass(BroadcastReceiver.class);
        ArgumentCaptor<BroadcastReceiver> carrierConfigCaptor =
        ArgumentCaptor<BroadcastReceiver> receiversCaptor =
                ArgumentCaptor.forClass(BroadcastReceiver.class);
        verify(mMockContext).registerReceiverAsUser(packageBroadcastCaptor.capture(), any(),
                any(), any(), any());
        verify(mMockContext).registerReceiver(carrierConfigCaptor.capture(), any());
        mTestCarrierConfigReceiver = carrierConfigCaptor.getValue();
        mTestPackageBroadcastReceiver = packageBroadcastCaptor.getValue();
        verify(mMockContext, times(2)).registerReceiver(receiversCaptor.capture(), any());
        mTestCarrierConfigReceiver = receiversCaptor.getAllValues().get(0);
        mTestBootCompleteReceiver = receiversCaptor.getAllValues().get(1);
        mTestImsResolver.setSubscriptionManagerProxy(mTestSubscriptionManagerProxy);
        when(mMockQueryManagerFactory.create(any(Context.class),
                any(ImsServiceFeatureQueryManager.Listener.class))).thenReturn(mMockQueryManager);
@@ -861,7 +907,7 @@ public class ImsResolverTest extends ImsTestBase {
    }

    private void startBind() {
        mTestImsResolver.initPopulateCacheAndStartBind();
        mTestImsResolver.initialize();
        ArgumentCaptor<ImsServiceFeatureQueryManager.Listener> queryManagerCaptor =
                ArgumentCaptor.forClass(ImsServiceFeatureQueryManager.Listener.class);
        verify(mMockQueryManagerFactory).create(any(Context.class), queryManagerCaptor.capture());
@@ -876,7 +922,7 @@ public class ImsResolverTest extends ImsTestBase {
        // ensure that startQuery was called
        when(mMockQueryManager.startQuery(any(ComponentName.class), any(String.class)))
                .thenReturn(true);
        verify(mMockQueryManager, Mockito.times(times)).startQuery(eq(name), any(String.class));
        verify(mMockQueryManager, times(times)).startQuery(eq(name), any(String.class));
        mDynamicQueryListener.onComplete(name, features);
        // wait for handling of onComplete
        waitForHandlerAction(mTestImsResolver.getHandler(), TEST_TIMEOUT);