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

Commit db8fcd41 authored by Brad Ebinger's avatar Brad Ebinger Committed by android-build-merger
Browse files

Adds compat layer for older devices when IMS binding

am: 0cd54345

Change-Id: If3706814316759a12eb46af15c77fd3e0bed2981
parents 7fb771d5 0cd54345
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -150,11 +150,17 @@ public class PhoneFactory {
                   where as in single SIM mode only instance. isMultiSimEnabled() function checks
                   whether it is single SIM or multi SIM mode */
                int numPhones = TelephonyManager.getDefault().getPhoneCount();
                // Start ImsResolver and bind to ImsServices.
                // Return whether or not the device should use dynamic binding or the static
                // implementation (deprecated)
                boolean isDynamicBinding = sContext.getResources().getBoolean(
                        com.android.internal.R.bool.config_dynamic_bind_ims);
                // Get the package name of the default IMS implementation.
                String defaultImsPackage = sContext.getResources().getString(
                        com.android.internal.R.string.config_ims_package);
                // Start ImsResolver and bind to ImsServices.
                Rlog.i(LOG_TAG, "ImsResolver: defaultImsPackage: " + defaultImsPackage);
                sImsResolver = new ImsResolver(sContext, defaultImsPackage, numPhones);
                sImsResolver = new ImsResolver(sContext, defaultImsPackage, numPhones,
                        isDynamicBinding);
                sImsResolver.populateCacheAndStartBind();

                int[] networkModes = new int[numPhones];
+61 −15
Original line number Diff line number Diff line
@@ -241,12 +241,28 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
                }
            };

    private ImsServiceControllerFactory mImsServiceControllerFactoryStaticBindingCompat =
            new ImsServiceControllerFactory() {
                @Override
                public String getServiceInterface() {
                    // The static method of binding does not use service interfaces.
                    return null;
                }

                @Override
                public ImsServiceController create(Context context, ComponentName componentName,
                        ImsServiceController.ImsServiceControllerCallbacks callbacks) {
                    return new ImsServiceControllerStaticCompat(context, componentName, callbacks);
                }
            };

    private final CarrierConfigManager mCarrierConfigManager;
    private final Context mContext;
    // Locks mBoundImsServicesByFeature only. Be careful to avoid deadlocks from
    // ImsServiceController callbacks.
    private final Object mBoundServicesLock = new Object();
    private final int mNumSlots;
    private final boolean mIsDynamicBinding;

    // Synchronize all messages on a handler to ensure that the cache includes the most recent
    // version of the installed ImsServices.
@@ -284,28 +300,41 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
    private Set<ImsServiceInfo> mInstalledServicesCache = new ArraySet<>();
    // not locked, only accessed on a handler thread.
    private Set<ImsServiceController> mActiveControllers = new ArraySet<>();
    // Only used as the
    private final ComponentName mStaticComponent;

    public ImsResolver(Context context, String defaultImsPackageName, int numSlots) {
    public ImsResolver(Context context, String defaultImsPackageName, int numSlots,
            boolean isDynamicBinding) {
        mContext = context;
        mDeviceService = defaultImsPackageName;
        mNumSlots = numSlots;
        mIsDynamicBinding = isDynamicBinding;
        mStaticComponent = new ComponentName(mContext, ImsResolver.class);
        if (!mIsDynamicBinding) {
            Log.i(TAG, "ImsResolver initialized with static binding.");
            mDeviceService = mStaticComponent.getPackageName();
        }
        mCarrierConfigManager = (CarrierConfigManager) mContext.getSystemService(
                Context.CARRIER_CONFIG_SERVICE);
        mCarrierServices = new String[numSlots];
        mBoundImsServicesByFeature = Stream.generate(SparseArray<ImsServiceController>::new)
                .limit(mNumSlots).collect(Collectors.toList());

        // Only register for Package/CarrierConfig updates if dynamic binding.
        if(mIsDynamicBinding) {
            IntentFilter appChangedFilter = new IntentFilter();
            appChangedFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
            appChangedFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
            appChangedFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
            appChangedFilter.addDataScheme("package");
        context.registerReceiverAsUser(mAppChangedReceiver, UserHandle.ALL, appChangedFilter, null,
            context.registerReceiverAsUser(mAppChangedReceiver, UserHandle.ALL, appChangedFilter,
                    null,
                    null);

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

    @VisibleForTesting
    public void setSubscriptionManagerProxy(SubscriptionManagerProxy proxy) {
@@ -500,7 +529,6 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
        }
    }


    // Update the current cache with the new ImsService(s) if it has been added or update the
    // supported IMS features if they have changed.
    // Called from the handler ONLY
@@ -783,10 +811,28 @@ public class ImsResolver implements ImsServiceController.ImsServiceControllerCal
    // get all packages that support ImsServices.
    private List<ImsServiceInfo> getImsServiceInfo(String packageName) {
        List<ImsServiceInfo> infos = new ArrayList<>();
        if (!mIsDynamicBinding) {
            // always return the same ImsService info.
            infos.addAll(getStaticImsService());
        } else {
            // Search for Current ImsService implementations
            infos.addAll(searchForImsServices(packageName, mImsServiceControllerFactory));
            // Search for compat ImsService Implementations
            infos.addAll(searchForImsServices(packageName, mImsServiceControllerFactoryCompat));
        }
        return infos;
    }

    private List<ImsServiceInfo> getStaticImsService() {
        List<ImsServiceInfo> infos = new ArrayList<>();

        ImsServiceInfo info = new ImsServiceInfo();
        info.name = mStaticComponent;
        info.supportedFeatures = new HashSet<>(ImsFeature.FEATURE_MAX);
        info.controllerFactory = mImsServiceControllerFactoryStaticBindingCompat;
        info.supportsEmergencyMmTel = true;
        info.supportedFeatures.add(ImsFeature.FEATURE_MMTEL);
        infos.add(info);
        return infos;
    }

+15 −2
Original line number Diff line number Diff line
@@ -334,8 +334,12 @@ public class ImsServiceController {
                        | Context.BIND_IMPORTANT;
                Log.i(LOG_TAG, "Binding ImsService:" + mComponentName);
                try {
                    return mContext.bindService(imsServiceIntent, mImsServiceConnection,
                            serviceFlags);
                    boolean bindSucceeded = startBindToService(imsServiceIntent,
                            mImsServiceConnection, serviceFlags);
                    if (!bindSucceeded) {
                        mBackoff.notifyFailed();
                    }
                    return bindSucceeded;
                } catch (Exception e) {
                    mBackoff.notifyFailed();
                    Log.e(LOG_TAG, "Error binding (" + mComponentName + ") with exception: "
@@ -349,6 +353,15 @@ public class ImsServiceController {
        }
    }

    /**
     * Starts the bind to the ImsService. Overridden by subclasses that need to access the service
     * in a different fashion.
     */
    protected boolean startBindToService(Intent intent, ImsServiceConnection connection,
            int flags) {
        return mContext.bindService(intent, connection, flags);
    }

    /**
     * Calls {@link IImsServiceController#removeImsFeature} on all features that the
     * ImsService supports and then unbinds the service.
+8 −2
Original line number Diff line number Diff line
@@ -160,15 +160,21 @@ public class ImsServiceControllerCompat extends ImsServiceController {
        return mServiceController != null;
    }

    private IImsMmTelFeature createMMTelCompat(int slotId, IImsFeatureStatusCallback c)
    protected MmTelInterfaceAdapter getInterface(int slotId, IImsFeatureStatusCallback c)
            throws RemoteException {
        IImsMMTelFeature feature = mServiceController.createMMTelFeature(slotId, c);
        if (feature == null) {
            Log.w(TAG, "createMMTelCompat: createMMTelFeature returned null.");
            return null;
        }
        return new MmTelInterfaceAdapter(slotId, feature.asBinder());
    }

    private IImsMmTelFeature createMMTelCompat(int slotId, IImsFeatureStatusCallback c)
            throws RemoteException {
        MmTelInterfaceAdapter interfaceAdapter = getInterface(slotId, c);
        MmTelFeatureCompatAdapter mmTelAdapter = new MmTelFeatureCompatAdapter(mContext, slotId,
                feature);
                interfaceAdapter);
        mMmTelCompatAdapters.put(slotId, mmTelAdapter);
        ImsRegistrationCompatAdapter regAdapter = new ImsRegistrationCompatAdapter();
        mmTelAdapter.addRegistrationAdapter(regAdapter);
+77 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.internal.telephony.ims;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;

import com.android.ims.internal.IImsFeatureStatusCallback;
import com.android.ims.internal.IImsService;

/**
 * A compat layer for communicating with older devices that still used the ServiceManager to get
 * the ImsService.
 */

public class ImsServiceControllerStaticCompat extends ImsServiceControllerCompat {

    private static final String TAG = "ImsSCStaticCompat";

    private static final String IMS_SERVICE_NAME = "ims";

    private IImsService mImsServiceCompat = null;

    public ImsServiceControllerStaticCompat(Context context, ComponentName componentName,
            ImsServiceController.ImsServiceControllerCallbacks callbacks) {
        super(context, componentName, callbacks);
    }

    @Override
    public boolean startBindToService(Intent intent, ImsServiceConnection connection, int flags) {
        IBinder binder = ServiceManager.checkService(IMS_SERVICE_NAME);

        if (binder == null) {
            return false;
        }
        // This is a little hacky, but we are going to call the onServiceConnected to "pretend" like
        // bindService has completed here, which will pass the binder to setServiceController and
        // set up all supporting structures.
        connection.onServiceConnected(new ComponentName(mContext,
                ImsServiceControllerStaticCompat.class), binder);
        return true;
    }

    @Override
    protected void setServiceController(IBinder serviceController) {
        mImsServiceCompat = IImsService.Stub.asInterface(serviceController);
    }

    @Override
    protected MmTelInterfaceAdapter getInterface(int slotId, IImsFeatureStatusCallback c)
            throws RemoteException {
        if (mImsServiceCompat == null) {
            Log.w(TAG, "getInterface: IImsService returned null.");
            return null;
        }
        return new ImsServiceInterfaceAdapter(slotId, mImsServiceCompat.asBinder());
    }
}
Loading