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

Commit 532570cd authored by Brad Ebinger's avatar Brad Ebinger Committed by Automerger Merge Worker
Browse files

Define new shell commands to get and modify UCE PUBLISH am: 685a2fce

Original change: https://android-review.googlesource.com/c/platform/frameworks/opt/net/ims/+/1587513

Change-Id: I1bb0862b8516df6ce8b336b8417e3689434f5a57
parents f1062230 685a2fce
Loading
Loading
Loading
Loading
+46 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Set;

/**
 * The UceController will manage the RCS UCE requests on a per subscription basis. When it receives
@@ -507,6 +508,51 @@ public class UceController {
        return mPublishController.getUcePublishState();
    }

    /**
     * Add new feature tags to the Set used to calculate the capabilities in PUBLISH.
     * <p>
     * Used for testing ONLY.
     * @return the new capabilities that will be used for PUBLISH.
     */
    public RcsContactUceCapability addRegistrationOverrideCapabilities(Set<String> featureTags) {
        return mPublishController.addRegistrationOverrideCapabilities(featureTags);
    }

    /**
     * Remove existing feature tags to the Set used to calculate the capabilities in PUBLISH.
     * <p>
     * Used for testing ONLY.
     * @return the new capabilities that will be used for PUBLISH.
     */
    public RcsContactUceCapability removeRegistrationOverrideCapabilities(Set<String> featureTags) {
        return mPublishController.removeRegistrationOverrideCapabilities(featureTags);
    }

    /**
     * Clear all overrides in the Set used to calculate the capabilities in PUBLISH.
     * <p>
     * Used for testing ONLY.
     * @return the new capabilities that will be used for PUBLISH.
     */
    public RcsContactUceCapability clearRegistrationOverrideCapabilities() {
        return mPublishController.clearRegistrationOverrideCapabilities();
    }

    /**
     * @return current RcsContactUceCapability instance that will be used for PUBLISH.
     */
    public RcsContactUceCapability getLatestRcsContactUceCapability() {
        return mPublishController.getLatestRcsContactUceCapability();
    }

    /**
     * Get the PIDF XML associated with the last successful publish or null if not PUBLISHed to the
     * network.
     */
    public String getLastPidfXml() {
        return mPublishController.getLastPidfXml();
    }

    /**
     * Get the subscription ID.
     */
+112 −18
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ import android.telephony.ims.RcsContactUceCapability.OptionsBuilder;
import android.telephony.ims.RcsContactUceCapability.PresenceBuilder;
import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.feature.MmTelFeature.MmTelCapabilities;
import android.util.ArraySet;
import android.util.LocalLog;
import android.util.Log;

import com.android.ims.rcs.uce.util.FeatureTags;
@@ -36,6 +38,7 @@ import com.android.ims.rcs.uce.util.UceUtils;
import com.android.internal.util.IndentingPrintWriter;

import java.io.PrintWriter;
import java.util.Collections;
import java.util.Set;

/**
@@ -46,9 +49,25 @@ public class DeviceCapabilityInfo {

    private final int mSubId;

    private final LocalLog mLocalLog = new LocalLog(UceUtils.LOG_SIZE);

    // Tracks capability status based on the IMS registration.
    private final PublishServiceDescTracker mServiceCapRegTracker;

    // FT overrides to add to the IMS registration, which will be added to the existing
    // capabilities.
    private final Set<String> mOverrideAddFeatureTags = new ArraySet<>();

    // FT overrides to remove from the existing IMS registration, which will remove the related
    // capabilities.
    private final Set<String> mOverrideRemoveFeatureTags = new ArraySet<>();

    // The feature tags associated with the last IMS registration update.
    private Set<String> mLastRegistrationFeatureTags = Collections.emptySet();
    // The feature tags associated with the last IMS registration update, which also include
    // overrides
    private Set<String> mLastRegistrationOverrideFeatureTags = Collections.emptySet();

    // The mmtel feature is registered or not
    private boolean mMmtelRegistered;

@@ -135,34 +154,93 @@ public class DeviceCapabilityInfo {

    /**
     * Update the status that IMS RCS is registered.
     * @return true if the IMS registration status changed, false if it did not.
     */
    public synchronized void updateImsRcsRegistered(ImsRegistrationAttributes attr) {
    public synchronized boolean updateImsRcsRegistered(ImsRegistrationAttributes attr) {
        StringBuilder builder = new StringBuilder();
        builder.append("IMS RCS registered: original state=").append(mRcsRegistered)
                .append(", changes type from ").append(mRcsNetworkRegType)
                .append(" to ").append(attr.getTransportType());
        logi(builder.toString());

        boolean changed = false;
        if (!mRcsRegistered) {
            mRcsRegistered = true;
            changed = true;
        }

        if (mRcsNetworkRegType != attr.getTransportType()) {
            mRcsNetworkRegType = attr.getTransportType();
            changed = true;
        }

        mServiceCapRegTracker.updateImsRegistration(attr.getFeatureTags());
        mLastRegistrationFeatureTags = attr.getFeatureTags();
        changed |= updateRegistration(mLastRegistrationFeatureTags);

        return changed;
    }

    /**
     * Update the status that IMS RCS is unregistered.
     */
    public synchronized void updateImsRcsUnregistered() {
    public synchronized boolean updateImsRcsUnregistered() {
        logi("IMS RCS unregistered: original state=" + mRcsRegistered);
        boolean changed = false;
        if (mRcsRegistered) {
            mRcsRegistered = false;
            changed = true;
        }
        mRcsNetworkRegType = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
        return changed;
    }

    public synchronized boolean addRegistrationOverrideCapabilities(Set<String> featureTags) {
        logd("override - add: " + featureTags);
        mOverrideRemoveFeatureTags.removeAll(featureTags);
        mOverrideAddFeatureTags.addAll(featureTags);
        // Call with the last feature tags so that the new ones will be potentially picked up.
        return updateRegistration(mLastRegistrationFeatureTags);
    };

    public synchronized boolean removeRegistrationOverrideCapabilities(Set<String> featureTags) {
        logd("override - remove: " + featureTags);
        mOverrideAddFeatureTags.removeAll(featureTags);
        mOverrideRemoveFeatureTags.addAll(featureTags);
        // Call with the last feature tags so that the new ones will be potentially picked up.
        return updateRegistration(mLastRegistrationFeatureTags);
    };

    public synchronized boolean clearRegistrationOverrideCapabilities() {
        logd("override - clear");
        mOverrideAddFeatureTags.clear();
        mOverrideRemoveFeatureTags.clear();
        // Call with the last feature tags so that base tags will be restored
        return updateRegistration(mLastRegistrationFeatureTags);
    };

    /**
     * Update the IMS registration tracked by the PublishServiceDescTracker if needed.
     * @return true if the registration changed, else otherwise.
     */
    private boolean updateRegistration(Set<String> baseTags) {
        Set<String> updatedTags = updateImsRegistrationFeatureTags(baseTags);
        if (!mLastRegistrationOverrideFeatureTags.equals(updatedTags)) {
            mLastRegistrationOverrideFeatureTags = updatedTags;
            mServiceCapRegTracker.updateImsRegistration(updatedTags);
            return true;
        }
        return false;
    }

    /**
     * Combine IMS registration with overrides to produce a new feature tag Set.
     * @return true if the IMS registration changed, false otherwise.
     */
    private synchronized Set<String> updateImsRegistrationFeatureTags(Set<String> featureTags) {
        Set<String> tags = new ArraySet<>(featureTags);
        tags.addAll(mOverrideAddFeatureTags);
        tags.removeAll(mOverrideRemoveFeatureTags);
        return tags;
    }

    /**
@@ -321,7 +399,8 @@ public class DeviceCapabilityInfo {
                ServiceDescription.SERVICE_DESCRIPTION_MMTEL_VOICE, capableFromReg);
        ServiceDescription vtDescription = getCustomizedDescription(
                ServiceDescription.SERVICE_DESCRIPTION_MMTEL_VOICE_VIDEO, capableFromReg);
        ServiceDescription descToUse = hasVtCapability() ? vtDescription : voiceDescription;
        ServiceDescription descToUse = (hasVolteCapability() && hasVtCapability()) ?
                vtDescription : voiceDescription;
        ServiceCapabilities servCaps = new ServiceCapabilities.Builder(
                hasVolteCapability(), hasVtCapability())
                .addSupportedDuplexMode(ServiceCapabilities.DUPLEX_MODE_FULL).build();
@@ -381,31 +460,39 @@ public class DeviceCapabilityInfo {

    // Check if the device has the VoLTE capability
    private synchronized boolean hasVolteCapability() {
        if (mMmTelCapabilities != null
                && mMmTelCapabilities.isCapable(MmTelCapabilities.CAPABILITY_TYPE_VOICE)) {
            return true;
        }
        return false;
        return overrideCapability(FeatureTags.FEATURE_TAG_MMTEL, mMmTelCapabilities != null
                && mMmTelCapabilities.isCapable(MmTelCapabilities.CAPABILITY_TYPE_VOICE));
    }

    // Check if the device has the VT capability
    private synchronized boolean hasVtCapability() {
        if (mMmTelCapabilities != null
                && mMmTelCapabilities.isCapable(MmTelCapabilities.CAPABILITY_TYPE_VIDEO)) {
            return true;
        }
        return false;
        return overrideCapability(FeatureTags.FEATURE_TAG_VIDEO, mMmTelCapabilities != null
                && mMmTelCapabilities.isCapable(MmTelCapabilities.CAPABILITY_TYPE_VIDEO));
    }

    // Check if the device has the Call Composer capability
    private synchronized boolean hasCallComposerCapability() {
        if (mMmTelCapabilities != null && mMmTelCapabilities.isCapable(
                MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER)) {
            return true;
        return overrideCapability(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY,
                mMmTelCapabilities != null && mMmTelCapabilities.isCapable(
                        MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER));
    }

    /**
     * @return the overridden value for the provided feature tag or the original capability if there
     * is no override.
     */
    private synchronized boolean overrideCapability(String featureTag, boolean originalCap) {
        if (mOverrideRemoveFeatureTags.contains(featureTag)) {
            return false;
        }

        if (mOverrideAddFeatureTags.contains(featureTag)) {
            return true;
        }

        return originalCap;
    }

    private synchronized MmTelCapabilities deepCopyCapabilities(MmTelCapabilities capabilities) {
        MmTelCapabilities mmTelCapabilities = new MmTelCapabilities();
        if (capabilities.isCapable(MmTelCapabilities.CAPABILITY_TYPE_VOICE)) {
@@ -428,14 +515,17 @@ public class DeviceCapabilityInfo {

    private void logd(String log) {
        Log.d(LOG_TAG, getLogPrefix().append(log).toString());
        mLocalLog.log("[D] " + log);
    }

    private void logi(String log) {
        Log.i(LOG_TAG, getLogPrefix().append(log).toString());
        mLocalLog.log("[I] " + log);
    }

    private void logw(String log) {
        Log.w(LOG_TAG, getLogPrefix().append(log).toString());
        mLocalLog.log("[W] " + log);
    }

    private StringBuilder getLogPrefix() {
@@ -450,9 +540,13 @@ public class DeviceCapabilityInfo {
        pw.println("DeviceCapabilityInfo :");
        pw.increaseIndent();

        pw.println("ServiceDescriptionTracker:");
        mServiceCapRegTracker.dump(pw);

        pw.println("Log:");
        pw.increaseIndent();
        mLocalLog.dump(pw);
        pw.decreaseIndent();

        pw.decreaseIndent();
    }
}
+7 −4
Original line number Diff line number Diff line
@@ -580,16 +580,19 @@ public class DeviceCapabilityListener {
     * This method is called when RCS is registered.
     */
    private void handleImsRcsRegistered(ImsRegistrationAttributes attr) {
        mCapabilityInfo.updateImsRcsRegistered(attr);
        if (mCapabilityInfo.updateImsRcsRegistered(attr)) {
            mHandler.sendTriggeringPublishMessage(PublishController.PUBLISH_TRIGGER_RCS_REGISTERED);
        }
    }

    /*
     * This method is called when RCS is unregistered.
     */
    private void handleImsRcsUnregistered() {
        mCapabilityInfo.updateImsRcsUnregistered();
        mHandler.sendTriggeringPublishMessage(PublishController.PUBLISH_TRIGGER_RCS_UNREGISTERED);
        if (mCapabilityInfo.updateImsRcsUnregistered()) {
            mHandler.sendTriggeringPublishMessage(
                    PublishController.PUBLISH_TRIGGER_RCS_UNREGISTERED);
        }
    }

    /*
+40 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.time.Instant;
import java.util.Set;

/**
 * The interface related to the PUBLISH request.
@@ -71,6 +72,9 @@ public interface PublishController extends ControllerBase {
    /** Publish trigger type: provisioning changes */
    int PUBLISH_TRIGGER_PROVISIONING_CHANGE = 12;

    /**The caps have been overridden for a test*/
    int PUBLISH_TRIGGER_OVERRIDE_CAPS = 13;

    @IntDef(value = {
            PUBLISH_TRIGGER_SERVICE,
            PUBLISH_TRIGGER_RETRY,
@@ -83,7 +87,8 @@ public interface PublishController extends ControllerBase {
            PUBLISH_TRIGGER_MMTEL_CAPABILITY_CHANGE,
            PUBLISH_TRIGGER_RCS_REGISTERED,
            PUBLISH_TRIGGER_RCS_UNREGISTERED,
            PUBLISH_TRIGGER_PROVISIONING_CHANGE
            PUBLISH_TRIGGER_PROVISIONING_CHANGE,
            PUBLISH_TRIGGER_OVERRIDE_CAPS
    }, prefix="PUBLISH_TRIGGER_")
    @Retention(RetentionPolicy.SOURCE)
    @interface PublishTriggerType {}
@@ -129,11 +134,45 @@ public interface PublishController extends ControllerBase {
        void updatePublishThrottle(int value);
    }

    /**
     * Add new feature tags to the Set used to calculate the capabilities in PUBLISH.
     * <p>
     * Used for testing ONLY.
     * @return the new capabilities that will be used for PUBLISH.
     */
    RcsContactUceCapability addRegistrationOverrideCapabilities(Set<String> featureTags);

    /**
     * Remove existing feature tags to the Set used to calculate the capabilities in PUBLISH.
     * <p>
     * Used for testing ONLY.
     * @return the new capabilities that will be used for PUBLISH.
     */
    RcsContactUceCapability removeRegistrationOverrideCapabilities(Set<String> featureTags);

    /**
     * Clear all overrides in the Set used to calculate the capabilities in PUBLISH.
     * <p>
     * Used for testing ONLY.
     * @return the new capabilities that will be used for PUBLISH.
     */
    RcsContactUceCapability clearRegistrationOverrideCapabilities();

    /**
     * @return latest RcsContactUceCapability instance that will be used for PUBLISH.
     */
    RcsContactUceCapability getLatestRcsContactUceCapability();

    /**
     * Retrieve the RCS UCE Publish state.
     */
    @PublishState int getUcePublishState();

    /**
     * @return the last PIDF XML used for publish or {@code null} if the device is not published.
     */
    String getLastPidfXml();

    /**
     * Notify that the device's capabilities have been unpublished from the network.
     */
+42 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

/**
 * The implementation of PublishController.
@@ -226,6 +227,44 @@ public class PublishControllerImpl implements PublishController {
        }
    }

    @Override
    public RcsContactUceCapability addRegistrationOverrideCapabilities(Set<String> featureTags) {
        if (mDeviceCapabilityInfo.addRegistrationOverrideCapabilities(featureTags)) {
            mPublishHandler.requestPublish(PublishController.PUBLISH_TRIGGER_OVERRIDE_CAPS);
        }
        return mDeviceCapabilityInfo.getDeviceCapabilities(
                RcsContactUceCapability.CAPABILITY_MECHANISM_PRESENCE, mContext);
    }

    @Override
    public RcsContactUceCapability removeRegistrationOverrideCapabilities(Set<String> featureTags) {
        if (mDeviceCapabilityInfo.removeRegistrationOverrideCapabilities(featureTags)) {
            mPublishHandler.requestPublish(PublishController.PUBLISH_TRIGGER_OVERRIDE_CAPS);
        }
        return mDeviceCapabilityInfo.getDeviceCapabilities(
                RcsContactUceCapability.CAPABILITY_MECHANISM_PRESENCE, mContext);
    }

    @Override
    public RcsContactUceCapability clearRegistrationOverrideCapabilities() {
        if (mDeviceCapabilityInfo.clearRegistrationOverrideCapabilities()) {
            mPublishHandler.requestPublish(PublishController.PUBLISH_TRIGGER_OVERRIDE_CAPS);
        }
        return mDeviceCapabilityInfo.getDeviceCapabilities(
                RcsContactUceCapability.CAPABILITY_MECHANISM_PRESENCE, mContext);
    }

    @Override
    public RcsContactUceCapability getLatestRcsContactUceCapability() {
        return mDeviceCapabilityInfo.getDeviceCapabilities(
                RcsContactUceCapability.CAPABILITY_MECHANISM_PRESENCE, mContext);
    }

    @Override
    public String getLastPidfXml() {
        return mPidfXml;
    }

    /**
     * Register a {@link PublishStateCallback} to listen to the published state changed.
     */
@@ -700,6 +739,9 @@ public class PublishControllerImpl implements PublishController {
            pw.println("mPublishProcessor is null");
        }

        pw.println();
        mDeviceCapListener.dump(pw);

        pw.println("Log:");
        pw.increaseIndent();
        mLocalLog.dump(pw);
Loading