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

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

Merge "Update IMS resolver/binding code to support multiuser" into main

parents 1260a6a8 0dc51ca9
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -138,6 +138,17 @@ flag {
    }
}

# OWNER=breadley TARGET=25Q1
flag {
    name: "ims_resolver_user_aware"
    namespace: "telephony"
    description: "When enabled, it makes ImsResolver mult-user aware for configurations like HSUM."
    bug:"371272669"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}

# OWNER=meghapatil TARGET=25Q2
flag {
    name: "support_sms_over_ims_apis"
+393 −113

File changed.

Preview size limit exceeded, changes collapsed.

+29 −17
Original line number Diff line number Diff line
@@ -196,7 +196,7 @@ public class ImsServiceController {
            }
            if (mCallbacks != null) {
                // Will trigger an unbind.
                mCallbacks.imsServiceBindPermanentError(getComponentName());
                mCallbacks.imsServiceBindPermanentError(getComponentName(), mBoundUser);
            }
        }

@@ -217,7 +217,8 @@ public class ImsServiceController {
        /**
         * Called by ImsServiceController when a new MMTEL or RCS feature has been created.
         */
        void imsServiceFeatureCreated(int slotId, int feature, ImsServiceController controller);
        void imsServiceFeatureCreated(int slotId, int subId, int feature,
                ImsServiceController controller);
        /**
         * Called by ImsServiceController when a new MMTEL or RCS feature has been removed.
         */
@@ -234,7 +235,7 @@ public class ImsServiceController {
         * Called by the ImsServiceController when there has been an error binding that is
         * not recoverable, such as the ImsService returning a null binder.
         */
        void imsServiceBindPermanentError(ComponentName name);
        void imsServiceBindPermanentError(ComponentName name, UserHandle user);
    }

    /**
@@ -273,6 +274,7 @@ public class ImsServiceController {

    private boolean mIsBound = false;
    private boolean mIsBinding = false;
    private UserHandle mBoundUser = null;
    // Set of a pair of slotId->feature
    private Set<ImsFeatureConfiguration.FeatureSlotPair> mImsFeatures;
    private SparseIntArray mSlotIdToSubIdMap;
@@ -337,7 +339,7 @@ public class ImsServiceController {
                if (mIsBound) {
                    return;
                }
                bind(mImsFeatures, mSlotIdToSubIdMap);
                bind(mBoundUser, mImsFeatures, mSlotIdToSubIdMap);
            }
        }
    };
@@ -413,17 +415,18 @@ public class ImsServiceController {
     * @return {@link true} if the service is in the process of being bound, {@link false} if it
     * has failed.
     */
    public boolean bind(Set<ImsFeatureConfiguration.FeatureSlotPair> imsFeatureSet,
    public boolean bind(UserHandle user, Set<ImsFeatureConfiguration.FeatureSlotPair> imsFeatureSet,
            SparseIntArray slotIdToSubIdMap) {
        synchronized (mLock) {
            if (!mIsBound && !mIsBinding) {
                mIsBinding = true;
                mBoundUser = user;
                sanitizeFeatureConfig(imsFeatureSet);
                mImsFeatures = imsFeatureSet;
                mSlotIdToSubIdMap = slotIdToSubIdMap;
                // Set the number of slots that support the feature
                mImsEnablementTracker.setNumOfSlots(mSlotIdToSubIdMap.size());
                grantPermissionsToService();
                grantPermissionsToService(user);
                Intent imsServiceIntent = new Intent(getServiceInterface()).setComponent(
                        mComponentName);
                mImsServiceConnection = new ImsServiceConnection();
@@ -432,8 +435,8 @@ public class ImsServiceController {
                mLocalLog.log("binding " + imsFeatureSet);
                Log.i(LOG_TAG, "Binding ImsService:" + mComponentName);
                try {
                    boolean bindSucceeded = mContext.bindService(imsServiceIntent,
                            mImsServiceConnection, serviceFlags);
                    boolean bindSucceeded = mContext.bindServiceAsUser(imsServiceIntent,
                            mImsServiceConnection, serviceFlags, user);
                    if (!bindSucceeded) {
                        mLocalLog.log("    binding failed, retrying in "
                                + mBackoff.getCurrentDelay() + " mS");
@@ -482,6 +485,7 @@ public class ImsServiceController {
            changeImsServiceFeatures(new HashSet<>(), mSlotIdToSubIdMap);
            mIsBound = false;
            mIsBinding = false;
            mBoundUser = null;
            setServiceController(null);
            unbindService();
        }
@@ -607,6 +611,13 @@ public class ImsServiceController {
        return mComponentName;
    }

    /**
     * @return The UserHandle that this controller is bound to or null if bound to no service.
     */
    public UserHandle getBoundUser() {
        return mBoundUser;
    }

    /**
     * Notify ImsService to enable IMS for the framework. This will trigger IMS registration and
     * trigger ImsFeature status updates.
@@ -766,7 +777,7 @@ public class ImsServiceController {

    // Grant runtime permissions to ImsService. PermissionManager ensures that the ImsService is
    // system/signed before granting permissions.
    private void grantPermissionsToService() {
    private void grantPermissionsToService(UserHandle user) {
        mLocalLog.log("grant permissions to " + getComponentName());
        Log.i(LOG_TAG, "Granting Runtime permissions to:" + getComponentName());
        String[] pkgToGrant = {mComponentName.getPackageName()};
@@ -774,8 +785,7 @@ public class ImsServiceController {
            if (mPermissionManager != null) {
                CountDownLatch latch = new CountDownLatch(1);
                mPermissionManager.grantDefaultPermissionsToEnabledImsServices(
                        pkgToGrant, UserHandle.of(UserHandle.myUserId()), Runnable::run,
                        isSuccess -> {
                        pkgToGrant, user, Runnable::run, isSuccess -> {
                            if (isSuccess) {
                                latch.countDown();
                            } else {
@@ -807,7 +817,8 @@ public class ImsServiceController {
            Log.i(LOG_TAG, "supports emergency calling on slot " + featurePair.slotId);
        }
        // Signal ImsResolver to change supported ImsFeatures for this ImsServiceController
        mCallbacks.imsServiceFeatureCreated(featurePair.slotId, featurePair.featureType, this);
        mCallbacks.imsServiceFeatureCreated(featurePair.slotId, subId, featurePair.featureType,
                this);
    }

    // This method should only be called when synchronized on mLock
@@ -978,10 +989,11 @@ public class ImsServiceController {
    @Override
    public String toString() {
        synchronized (mLock) {
            return "[ImsServiceController: componentName=" + getComponentName() + ", features="
                    + mImsFeatures + ", isBinding=" + mIsBinding + ", isBound=" + mIsBound
                    + ", serviceController=" + getImsServiceController() + ", rebindDelay="
                    + getRebindDelay() + "]";
            return "[ImsServiceController: componentName=" + getComponentName() + ", boundUser="
                    + mBoundUser + ", features=" + mImsFeatures + ", isBinding=" + mIsBinding
                    + ", isBound=" + mIsBound + ", serviceController=" + getImsServiceController()
                    + ", rebindDelay=" + getRebindDelay() + ", slotToSubIdMap=" + mSlotIdToSubIdMap
                    + "]";
        }
    }

+12 −7
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.UserHandle;
import android.telephony.ims.aidl.IImsServiceController;
import android.telephony.ims.stub.ImsFeatureConfiguration;
import android.util.Log;
@@ -42,14 +43,16 @@ public class ImsServiceFeatureQueryManager {
        private static final String LOG_TAG = "ImsServiceFeatureQuery";

        private final ComponentName mName;
        private final UserHandle mUser;
        private final String mIntentFilter;
        // Track the status of whether or not the Service has died in case we need to permanently
        // unbind (see onNullBinding below).
        private boolean mIsServiceConnectionDead = false;


        ImsServiceFeatureQuery(ComponentName name, String intentFilter) {
        ImsServiceFeatureQuery(ComponentName name, UserHandle user, String intentFilter) {
            mName = name;
            mUser = user;
            mIntentFilter = intentFilter;
        }

@@ -62,7 +65,8 @@ public class ImsServiceFeatureQueryManager {
            Intent imsServiceIntent = new Intent(mIntentFilter).setComponent(mName);
            int serviceFlags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
                    | Context.BIND_IMPORTANT;
            boolean bindStarted = mContext.bindService(imsServiceIntent, this, serviceFlags);
            boolean bindStarted = mContext.bindServiceAsUser(imsServiceIntent, this,
                    serviceFlags, mUser);
            if (!bindStarted) {
                // Docs say to unbind if this fails.
                cleanup();
@@ -78,7 +82,7 @@ public class ImsServiceFeatureQueryManager {
            } else {
                Log.w(LOG_TAG, "onServiceConnected: " + name + " binder null.");
                cleanup();
                mListener.onPermanentError(name);
                mListener.onPermanentError(name, mUser);
            }
        }

@@ -103,7 +107,7 @@ public class ImsServiceFeatureQueryManager {
            // permanently unbind and instead let the automatic rebind occur.
            if (mIsServiceConnectionDead) return;
            cleanup();
            mListener.onPermanentError(name);
            mListener.onPermanentError(name, mUser);
        }

        private void queryImsFeatures(IImsServiceController controller) {
@@ -154,7 +158,7 @@ public class ImsServiceFeatureQueryManager {
        /**
         * Called when a query has failed due to a permanent error and should not be retried.
         */
        void onPermanentError(ComponentName name);
        void onPermanentError(ComponentName name, UserHandle user);
    }

    // Maps an active ImsService query (by Package Name String) its query.
@@ -171,16 +175,17 @@ public class ImsServiceFeatureQueryManager {
    /**
     * Starts an ImsService feature query for the ComponentName and Intent specified.
     * @param name The ComponentName of the ImsService being queried.
     * @param user The User associated with the request.
     * @param intentFilter The Intent filter that the ImsService specified.
     * @return true if the query started, false if it was unable to start.
     */
    public boolean startQuery(ComponentName name, String intentFilter) {
    public boolean startQuery(ComponentName name, UserHandle user, String intentFilter) {
        synchronized (mLock) {
            if (mActiveQueries.containsKey(name)) {
                // We already have an active query, wait for it to return.
                return true;
            }
            ImsServiceFeatureQuery query = new ImsServiceFeatureQuery(name, intentFilter);
            ImsServiceFeatureQuery query = new ImsServiceFeatureQuery(name, user, intentFilter);
            mActiveQueries.put(name, query);
            return query.start();
        }
+355 −109

File changed.

Preview size limit exceeded, changes collapsed.

Loading