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

Commit 093382b9 authored by James.cf Lin's avatar James.cf Lin Committed by Brad Ebinger
Browse files

[RCS UCE] Do not trigger publish if the RCS capability presence uce is not enabled

Bug: 174187744
Test: atest -c CtsTelephonyTestCases:android.telephony.ims.cts.ImsServiceTest
Merged-In: Ib3ff6975313e18beb21e7bfcdf6aa0592992eb52
Change-Id: Ib3ff6975313e18beb21e7bfcdf6aa0592992eb52
parent ca4f1a8e
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -388,9 +388,13 @@ public class RcsFeatureManager implements FeatureUpdates {
    /**
     * Query the availability of an IMS RCS capability.
     */
    public boolean isAvailable(@RcsImsCapabilities.RcsImsCapabilityFlag int capability)
    public boolean isAvailable(@RcsImsCapabilities.RcsImsCapabilityFlag int capability,
            @ImsRegistrationImplBase.ImsRegistrationTech int radioTech)
            throws android.telephony.ims.ImsException {
        try {
            if (mRcsFeatureConnection.getRegistrationTech() != radioTech) {
                return false;
            }
            int currentStatus = mRcsFeatureConnection.queryCapabilityStatus();
            return new RcsImsCapabilities(currentStatus).isCapable(capability);
        } catch (RemoteException e) {
+66 −0
Original line number Diff line number Diff line
@@ -23,10 +23,13 @@ import android.os.Looper;
import android.os.Message;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.telephony.ims.ImsException;
import android.telephony.ims.RcsContactUceCapability;
import android.telephony.ims.RcsUceAdapter;
import android.telephony.ims.RcsUceAdapter.PublishState;
import android.telephony.ims.aidl.IImsCapabilityCallback;
import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
import android.telephony.ims.feature.RcsFeature.RcsImsCapabilities;
import android.util.Log;

import com.android.ims.RcsFeatureManager;
@@ -68,6 +71,8 @@ public class PublishControllerImpl implements PublishController {
    private final Context mContext;
    private PublishHandler mPublishHandler;
    private volatile boolean mIsDestroyedFlag;
    private volatile boolean mCapabilityPresenceEnabled;
    private volatile RcsFeatureManager mRcsFeatureManager;
    private final UceControllerCallback mUceCtrlCallback;

    // The device publish state
@@ -94,6 +99,31 @@ public class PublishControllerImpl implements PublishController {
            (context, subId, capInfo, callback, looper)
                    -> new DeviceCapabilityListener(context, subId, capInfo, callback, looper);

    // Listen to the RCS availability status changed.
    private final IImsCapabilityCallback mRcsCapabilitiesCallback =
            new IImsCapabilityCallback.Stub() {
        @Override
        public void onQueryCapabilityConfiguration(
                int resultCapability, int resultRadioTech, boolean enabled) {
        }
        @Override
        public void onCapabilitiesStatusChanged(int capabilities) {
            logd("onCapabilitiesStatusChanged: " + capabilities);
            RcsImsCapabilities RcsImsCapabilities = new RcsImsCapabilities(capabilities);
            mCapabilityPresenceEnabled =
                    RcsImsCapabilities.isCapable(RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE);

            // Trigger a publish request if the RCS capabilities presence is enabled.
            if (mCapabilityPresenceEnabled) {
                mPublishProcessor.checkAndSendPendingRequest();
            }
        }
        @Override
        public void onChangeCapabilityConfigurationError(int capability, int radioTech,
                int reason) {
        }
    };

    public PublishControllerImpl(Context context, int subId, UceControllerCallback callback,
            Looper looper) {
        mSubId = subId;
@@ -142,12 +172,16 @@ public class PublishControllerImpl implements PublishController {
    @Override
    public void onRcsConnected(RcsFeatureManager manager) {
        logd("onRcsConnected");
        mRcsFeatureManager = manager;
        mPublishProcessor.onRcsConnected(manager);
        registerRcsAvailabilityChanged(manager);
    }

    @Override
    public void onRcsDisconnected() {
        logd("onRcsDisconnected");
        mRcsFeatureManager = null;
        mCapabilityPresenceEnabled = false;
        mPublishProcessor.onRcsDisconnected();
    }

@@ -155,6 +189,8 @@ public class PublishControllerImpl implements PublishController {
    public void onDestroy() {
        logi("onDestroy");
        mIsDestroyedFlag = true;
        mCapabilityPresenceEnabled = false;
        unregisterRcsAvailabilityChanged();
        mDeviceCapListener.onDestroy();   // It will turn off the listener automatically.
        mPublishHandler.onDestroy();
        mPublishProcessor.onDestroy();
@@ -225,6 +261,24 @@ public class PublishControllerImpl implements PublishController {
        return mDeviceCapabilityInfo.getDeviceCapabilities(mContext);
    }

    private void registerRcsAvailabilityChanged(RcsFeatureManager manager) {
        try {
            manager.registerRcsAvailabilityCallback(mSubId, mRcsCapabilitiesCallback);
        } catch (ImsException e) {
            logw("registerRcsAvailabilityChanged exception " + e);
        }
    }

    private void unregisterRcsAvailabilityChanged() {
        RcsFeatureManager manager = mRcsFeatureManager;
        if (manager == null) return;
        try {
            manager.unregisterRcsAvailabilityCallback(mSubId, mRcsCapabilitiesCallback);
        } catch (Exception e) {
            // Do not handle the exception
        }
    }

    // The local publish request from the sub-components which interact with PublishController.
    private final PublishControllerCallback mPublishControllerCallback =
            new PublishControllerCallback() {
@@ -378,6 +432,13 @@ public class PublishControllerImpl implements PublishController {
            if (publishCtrl.mIsDestroyedFlag) return;
            publishCtrl.logd("requestPublish: " + type + ", delay=" + delay);

            // Return if the RCS capabilities presence uce is not enabled.
            if (!publishCtrl.mCapabilityPresenceEnabled) {
                publishCtrl.logd("requestPublish: Skip. capability presence uce is not enabled.");
                publishCtrl.mPublishProcessor.setPendingRequest(true);
                return;
            }

            // Don't send duplicated publish request because it always publish the latest device
            // capabilities.
            if (hasMessages(MSG_REQUEST_PUBLISH)) {
@@ -520,6 +581,11 @@ public class PublishControllerImpl implements PublishController {
        return mPublishHandler;
    }

    @VisibleForTesting
    public IImsCapabilityCallback getRcsCapabilitiesCallback() {
        return mRcsCapabilitiesCallback;
    }

    private void logd(String log) {
        Log.d(LOG_TAG, getLogPrefix().append(log).toString());
    }
+21 −20
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.ims.rcs.uce.presence.publish;

import android.annotation.NonNull;
import android.content.Context;
import android.os.RemoteException;
import android.telephony.ims.RcsContactUceCapability;
@@ -131,8 +132,16 @@ public class PublishProcessor {
            return;
        }

        // Set the pending request and return if RCS is not connected.
        RcsFeatureManager featureManager = mRcsFeatureManager;
        if (featureManager == null) {
            logw("doPublish: NOT connected");
            setPendingRequest(true);
            return;
        }

        // Publish to the Presence server.
        publishCapabilities(pidfXml);
        publishCapabilities(featureManager, pidfXml);
    }

    // Check if the giving trigger type should reset the retry count.
@@ -169,7 +178,7 @@ public class PublishProcessor {
        // Set the pending flag if there's already a request running now.
        if (mProcessorState.isPublishingNow()) {
            logd("isPublishAllowed: There is already a request running now");
            mProcessorState.setPendingRequest(true);
            setPendingRequest(true);
            return false;
        }

@@ -186,27 +195,15 @@ public class PublishProcessor {
    }

    // Publish the device capabilities with the given pidf
    private void publishCapabilities(String pidfXml) {
        if (mIsDestroyed) {
            logw("publishCapabilities: This instance is already destroyed");
            return;
        }

        // Check if the RCS is connected.
        RcsFeatureManager featureManager = mRcsFeatureManager;
        if (featureManager == null) {
            mLocalLog.log("publish capabilities: not connected");
            logw("publishCapabilities: NOT connected");
            return;
        }

    private void publishCapabilities(@NonNull RcsFeatureManager featureManager,
            @NonNull String pidfXml) {
        PublishRequestResponse requestResponse = null;
        try {
            // Set publishing flag
            mProcessorState.setPublishingFlag(true);

            // Clear the pending request flag since we're publishing the latest device's capability
            mProcessorState.setPendingRequest(false);
            setPendingRequest(false);

            // Generate a unique taskId to track this request.
            long taskId = mProcessorState.generatePublishTaskId();
@@ -251,7 +248,7 @@ public class PublishProcessor {
            mProcessorState.increaseRetryCount();

            // Reset the pending flag since it is going to resend a publish request.
            mProcessorState.setPendingRequest(false);
            setPendingRequest(false);

            // Resend a publish request
            long delayTime = mProcessorState.getDelayTimeToAllowPublish();
@@ -292,7 +289,7 @@ public class PublishProcessor {
            mProcessorState.increaseRetryCount();

            // Reset the pending flag since it is going to resend a publish request.
            mProcessorState.setPendingRequest(false);
            setPendingRequest(false);

            // Resend a publish request
            long delayTime = mProcessorState.getDelayTimeToAllowPublish();
@@ -369,7 +366,11 @@ public class PublishProcessor {
        logd("setRequestEnded: taskId=" + taskId);
    }

    private void checkAndSendPendingRequest() {
    public void setPendingRequest(boolean pendingRequest) {
        mProcessorState.setPendingRequest(pendingRequest);
    }

    public void checkAndSendPendingRequest() {
        if (mIsDestroyed) return;
        if (mProcessorState.hasPendingRequest()) {
            logd("checkAndSendPendingRequest: send pending request");
+7 −1
Original line number Diff line number Diff line
@@ -21,12 +21,14 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;

import android.os.Handler;
import android.os.Looper;
import android.os.RemoteCallbackList;
import android.telephony.ims.RcsUceAdapter;
import android.telephony.ims.aidl.IImsCapabilityCallback;
import android.telephony.ims.aidl.IRcsUcePublishStateCallback;

import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -159,7 +161,11 @@ public class PublishControllerImplTest extends ImsTestBase {

        Handler handler = publishController.getPublishHandler();
        waitForHandlerAction(handler, 1000);
        verify(mPublishProcessor).doPublish(PublishController.PUBLISH_TRIGGER_SERVICE);
        verify(mPublishProcessor, never()).doPublish(PublishController.PUBLISH_TRIGGER_SERVICE);

        IImsCapabilityCallback callback = publishController.getRcsCapabilitiesCallback();
        callback.onCapabilitiesStatusChanged(RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE);
        verify(mPublishProcessor).checkAndSendPendingRequest();
    }

    private PublishControllerImpl createPublishController() {