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

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

Merge "Add the ability to include RCS capabilities in SIP PUBLISH" am: e6a96d3b

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

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Id8cc72dc68bfb5583aadaf9721eedce0f5fa10c2
parents 9b22f5e7 e6a96d3b
Loading
Loading
Loading
Loading
+90 −24
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.content.Context;
import android.net.Uri;
import android.telecom.TelecomManager;
import android.telephony.AccessNetworkConstants;
import android.telephony.ims.ImsRegistrationAttributes;
import android.telephony.ims.RcsContactPresenceTuple;
import android.telephony.ims.RcsContactPresenceTuple.ServiceCapabilities;
import android.telephony.ims.RcsContactUceCapability;
@@ -32,6 +33,10 @@ import android.util.Log;

import com.android.ims.rcs.uce.util.FeatureTags;
import com.android.ims.rcs.uce.util.UceUtils;
import com.android.internal.util.IndentingPrintWriter;

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

/**
 * Stores the device's capabilities information.
@@ -41,6 +46,9 @@ public class DeviceCapabilityInfo {

    private final int mSubId;

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

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

@@ -50,6 +58,9 @@ public class DeviceCapabilityInfo {
    // The rcs feature is registered or not
    private boolean mRcsRegistered;

    // Whether or not presence is reported as capable
    private boolean mPresenceCapable;

    // The network type which ims rcs registers on.
    private int mRcsNetworkRegType;

@@ -62,8 +73,9 @@ public class DeviceCapabilityInfo {
    private boolean mMobileData;
    private boolean mVtSetting;

    public DeviceCapabilityInfo(int subId) {
    public DeviceCapabilityInfo(int subId, String[] capToRegistrationMap) {
        mSubId = subId;
        mServiceCapRegTracker = PublishServiceDescTracker.fromCarrierConfig(capToRegistrationMap);
        reset();
    }

@@ -117,23 +129,29 @@ public class DeviceCapabilityInfo {
        mMmtelNetworkRegType = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
    }

    public synchronized void updatePresenceCapable(boolean isCapable) {
        mPresenceCapable = isCapable;
    }

    /**
     * Update the status that IMS RCS is registered.
     */
    public synchronized void updateImsRcsRegistered(int type) {
    public synchronized void 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(type);
                .append(" to ").append(attr.getTransportType());
        logi(builder.toString());

        if (!mRcsRegistered) {
            mRcsRegistered = true;
        }

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

        mServiceCapRegTracker.updateImsRegistration(attr.getFeatureTags());
    }

    /**
@@ -234,6 +252,10 @@ public class DeviceCapabilityInfo {
        return false;
    }

    public synchronized boolean isPresenceCapable() {
        return mPresenceCapable;
    }

    private boolean isVolteAvailable(int networkRegType, MmTelCapabilities capabilities) {
        return (networkRegType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                && capabilities.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
@@ -282,33 +304,59 @@ public class DeviceCapabilityInfo {
            logw("getPresenceCapabilities: uri is empty");
            return null;
        }
        ServiceCapabilities.Builder servCapsBuilder = new ServiceCapabilities.Builder(
                hasVolteCapability(), hasVtCapability());
        servCapsBuilder.addSupportedDuplexMode(ServiceCapabilities.DUPLEX_MODE_FULL);

        RcsContactPresenceTuple.Builder tupleBuilder = new RcsContactPresenceTuple.Builder(
                RcsContactPresenceTuple.TUPLE_BASIC_STATUS_OPEN,
                RcsContactPresenceTuple.SERVICE_ID_MMTEL, "1.0");
        tupleBuilder.setContactUri(uri).setServiceCapabilities(servCapsBuilder.build());

        RcsContactPresenceTuple.Builder callComposerTupleBuilder =
                new RcsContactPresenceTuple.Builder(
                        RcsContactPresenceTuple.TUPLE_BASIC_STATUS_OPEN,
                        RcsContactPresenceTuple.SERVICE_ID_CALL_COMPOSER, "2.0");
        callComposerTupleBuilder.setContactUri(uri).setServiceCapabilities(
                servCapsBuilder.build());
        Set<ServiceDescription> capableFromReg =
                mServiceCapRegTracker.copyRegistrationCapabilities();

        PresenceBuilder presenceBuilder = new PresenceBuilder(uri,
                RcsContactUceCapability.SOURCE_TYPE_CACHED,
                RcsContactUceCapability.REQUEST_RESULT_FOUND);
        presenceBuilder.addCapabilityTuple(tupleBuilder.build());
        // RCS presence tag (added to all presence documents)
        ServiceDescription presDescription = getCustomizedDescription(
                ServiceDescription.SERVICE_DESCRIPTION_PRESENCE, capableFromReg);
        addCapability(presenceBuilder, presDescription.getTupleBuilder(), uri);
        capableFromReg.remove(presDescription);

        // mmtel
        ServiceDescription voiceDescription = getCustomizedDescription(
                ServiceDescription.SERVICE_DESCRIPTION_MMTEL_VOICE, capableFromReg);
        ServiceDescription vtDescription = getCustomizedDescription(
                ServiceDescription.SERVICE_DESCRIPTION_MMTEL_VOICE_VIDEO, capableFromReg);
        ServiceDescription descToUse = hasVtCapability() ? vtDescription : voiceDescription;
        ServiceCapabilities servCaps = new ServiceCapabilities.Builder(
                hasVolteCapability(), hasVtCapability())
                .addSupportedDuplexMode(ServiceCapabilities.DUPLEX_MODE_FULL).build();
        addCapability(presenceBuilder, descToUse.getTupleBuilder()
                .setServiceCapabilities(servCaps), uri);
        capableFromReg.remove(voiceDescription);
        capableFromReg.remove(vtDescription);

        // call composer via mmtel
        ServiceDescription composerDescription = getCustomizedDescription(
                ServiceDescription.SERVICE_DESCRIPTION_CALL_COMPOSER_MMTEL, capableFromReg);
        if (hasCallComposerCapability()) {
            presenceBuilder.addCapabilityTuple(callComposerTupleBuilder.build());
            addCapability(presenceBuilder, composerDescription.getTupleBuilder(), uri);
        }
        capableFromReg.remove(composerDescription);

        // External features can only be found using registration states from other components.
        // Count these features as capable and include in PIDF XML if they are registered.
        for (ServiceDescription capability : capableFromReg) {
            addCapability(presenceBuilder, capability.getTupleBuilder(), uri);
        }

        return presenceBuilder.build();
    }

    /**
     * Search the refSet for the ServiceDescription that matches the service-id && version and
     * return that or return the reference if there is no match.
     */
    private ServiceDescription getCustomizedDescription(ServiceDescription reference,
            Set<ServiceDescription> refSet) {
        return refSet.stream().filter(s -> s.serviceId.equals(reference.serviceId)
                && s.version.equals(reference.version)).findFirst().orElse(reference);
    }

    // Get the device's capabilities with the OPTIONS mechanism.
    private RcsContactUceCapability getOptionsCapabilities(Context context) {
        Uri uri = PublishUtils.getDeviceContactUri(context, mSubId);
@@ -317,13 +365,20 @@ public class DeviceCapabilityInfo {
            return null;
        }

        Set<String> capableFromReg = mServiceCapRegTracker.copyRegistrationFeatureTags();

        OptionsBuilder optionsBuilder = new OptionsBuilder(uri);
        optionsBuilder.setRequestResult(RcsContactUceCapability.REQUEST_RESULT_FOUND);
        FeatureTags.addMmTelFeatureTags(optionsBuilder,
                hasVolteCapability(), hasVtCapability());
        FeatureTags.addFeatureTags(optionsBuilder, hasVolteCapability(), hasVtCapability(),
                isPresenceCapable(), hasCallComposerCapability(), capableFromReg);
        return optionsBuilder.build();
    }

    private void addCapability(RcsContactUceCapability.PresenceBuilder presenceBuilder,
            RcsContactPresenceTuple.Builder tupleBuilder, Uri contactUri) {
        presenceBuilder.addCapabilityTuple(tupleBuilder.setContactUri(contactUri).build());
    }

    // Check if the device has the VoLTE capability
    private synchronized boolean hasVolteCapability() {
        if (mMmTelCapabilities != null
@@ -389,4 +444,15 @@ public class DeviceCapabilityInfo {
        builder.append("] ");
        return builder;
    }

    public void dump(PrintWriter printWriter) {
        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
        pw.println("DeviceCapabilityInfo :");
        pw.increaseIndent();

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

        pw.decreaseIndent();
    }
}
+30 −5
Original line number Diff line number Diff line
@@ -34,15 +34,20 @@ import android.telephony.ims.ImsMmTelManager;
import android.telephony.ims.ImsMmTelManager.CapabilityCallback;
import android.telephony.ims.ImsRcsManager;
import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.ImsRegistrationAttributes;
import android.telephony.ims.ProvisioningManager;
import android.telephony.ims.RegistrationManager;
import android.telephony.ims.feature.MmTelFeature.MmTelCapabilities;
import android.util.LocalLog;
import android.util.Log;

import com.android.ims.rcs.uce.presence.publish.PublishController.PublishControllerCallback;
import com.android.ims.rcs.uce.util.UceUtils;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.util.HandlerExecutor;
import com.android.internal.util.IndentingPrintWriter;

import java.io.PrintWriter;

/**
 * Listen to the device changes and notify the PublishController to publish the device's
@@ -113,6 +118,7 @@ public class DeviceCapabilityListener {

    private final int mSubId;
    private final Context mContext;
    private final LocalLog mLocalLog = new LocalLog(UceUtils.LOG_SIZE);
    private volatile boolean mInitialized;

    // The listener is destroyed
@@ -373,10 +379,10 @@ public class DeviceCapabilityListener {
    public final RegistrationManager.RegistrationCallback mRcsRegistrationCallback =
            new RegistrationManager.RegistrationCallback() {
                @Override
                public void onRegistered(int imsTransportType) {
                public void onRegistered(ImsRegistrationAttributes attributes) {
                    synchronized (mLock) {
                        logi("onRcsRegistered: " + imsTransportType);
                        handleImsRcsRegistered(imsTransportType);
                        logi("onRcsRegistered: " + attributes);
                        handleImsRcsRegistered(attributes);
                    }
                }

@@ -507,8 +513,8 @@ public class DeviceCapabilityListener {
    /*
     * This method is called when the RCS is registered.
     */
    private void handleImsRcsRegistered(int imsTransportType) {
        mCapabilityInfo.updateImsRcsRegistered(imsTransportType);
    private void handleImsRcsRegistered(ImsRegistrationAttributes attr) {
        mCapabilityInfo.updateImsRcsRegistered(attr);
        mCallback.requestPublishFromInternal(
                PublishController.PUBLISH_TRIGGER_RCS_REGISTERED,
                DELAY_SEND_IMS_REGISTERED_CHANGED_MSG);
@@ -545,14 +551,17 @@ public class DeviceCapabilityListener {

    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() {
@@ -561,4 +570,20 @@ public class DeviceCapabilityListener {
        builder.append("] ");
        return builder;
    }

    public void dump(PrintWriter printWriter) {
        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
        pw.println("DeviceCapListener" + "[subId: " + mSubId + "]:");
        pw.increaseIndent();

        mCapabilityInfo.dump(pw);

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

        pw.decreaseIndent();
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -121,7 +121,7 @@ public interface PublishController extends ControllerBase {
        /**
         * Update the publish request result.
         */
        void updatePublishRequestResult(int publishState, Instant updatedTimestamp);
        void updatePublishRequestResult(int publishState, Instant updatedTimestamp, String pidfXml);
    }

    /**
+45 −21
Original line number Diff line number Diff line
@@ -21,8 +21,10 @@ import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.PersistableBundle;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.telephony.CarrierConfigManager;
import android.telephony.ims.ImsException;
import android.telephony.ims.RcsContactUceCapability;
import android.telephony.ims.RcsContactUceCapability.CapabilityMechanism;
@@ -38,6 +40,7 @@ import com.android.ims.RcsFeatureManager;
import com.android.ims.rcs.uce.UceController.UceControllerCallback;
import com.android.ims.rcs.uce.util.UceUtils;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.IndentingPrintWriter;

import java.io.PrintWriter;
@@ -76,7 +79,6 @@ public class PublishControllerImpl implements PublishController {
    private final LocalLog mLocalLog = new LocalLog(UceUtils.LOG_SIZE);
    private PublishHandler mPublishHandler;
    private volatile boolean mIsDestroyedFlag;
    private volatile boolean mCapabilityPresenceEnabled;
    private volatile boolean mReceivePublishFromService;
    private volatile RcsFeatureManager mRcsFeatureManager;
    private final UceControllerCallback mUceCtrlCallback;
@@ -85,6 +87,8 @@ public class PublishControllerImpl implements PublishController {
    private @PublishState int mPublishState;
    // The timestamp of updating the publish state
    private Instant mPublishStateUpdatedTime = Instant.now();
    // The last PIDF XML used in the publish
    private String mPidfXml;

    // The callbacks to notify publish state changed.
    private RemoteCallbackList<IRcsUcePublishStateCallback> mPublishStateCallbacks;
@@ -116,11 +120,11 @@ public class PublishControllerImpl implements PublishController {
        public void onCapabilitiesStatusChanged(int capabilities) {
            logd("onCapabilitiesStatusChanged: " + capabilities);
            RcsImsCapabilities RcsImsCapabilities = new RcsImsCapabilities(capabilities);
            mCapabilityPresenceEnabled =
                    RcsImsCapabilities.isCapable(RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE);
            mDeviceCapabilityInfo.updatePresenceCapable(
                    RcsImsCapabilities.isCapable(RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE));

            // Trigger a publish request if the RCS capabilities presence is enabled.
            if (mCapabilityPresenceEnabled) {
            if (mDeviceCapabilityInfo.isPresenceCapable()) {
                mPublishProcessor.checkAndSendPendingRequest();
            }
        }
@@ -156,7 +160,14 @@ public class PublishControllerImpl implements PublishController {
        mPublishStateCallbacks = new RemoteCallbackList<>();

        mPublishHandler = new PublishHandler(this, looper);
        mDeviceCapabilityInfo = new DeviceCapabilityInfo(mSubId);

        CarrierConfigManager manager = mContext.getSystemService(CarrierConfigManager.class);
        PersistableBundle bundle = manager != null ? manager.getConfigForSubId(mSubId) :
                CarrierConfigManager.getDefaultConfig();
        String[] serviceDescFeatureTagMap = bundle.getStringArray(
                CarrierConfigManager.Ims.
                        KEY_PUBLISH_SERVICE_DESC_FEATURE_TAG_MAP_OVERRIDE_STRING_ARRAY);
        mDeviceCapabilityInfo = new DeviceCapabilityInfo(mSubId, serviceDescFeatureTagMap);

        initPublishProcessor();
        initDeviceCapabilitiesListener();
@@ -187,7 +198,7 @@ public class PublishControllerImpl implements PublishController {
    public void onRcsDisconnected() {
        logd("onRcsDisconnected");
        mRcsFeatureManager = null;
        mCapabilityPresenceEnabled = false;
        mDeviceCapabilityInfo.updatePresenceCapable(false);
        mPublishProcessor.onRcsDisconnected();
    }

@@ -195,7 +206,7 @@ public class PublishControllerImpl implements PublishController {
    public void onDestroy() {
        logi("onDestroy");
        mIsDestroyedFlag = true;
        mCapabilityPresenceEnabled = false;
        mDeviceCapabilityInfo.updatePresenceCapable(false);
        unregisterRcsAvailabilityChanged();
        mDeviceCapListener.onDestroy();   // It will turn off the listener automatically.
        mPublishHandler.onDestroy();
@@ -259,7 +270,7 @@ public class PublishControllerImpl implements PublishController {
        logd("onUnpublish");
        if (mIsDestroyedFlag) return;
        mPublishHandler.onPublishStateChanged(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
                Instant.now());
                Instant.now(), null /*pidfXml*/);
    }

    @Override
@@ -330,9 +341,9 @@ public class PublishControllerImpl implements PublishController {

                @Override
                public void updatePublishRequestResult(@PublishState int publishState,
                        Instant updatedTime) {
                        Instant updatedTime, String pidfXml) {
                    logd("updatePublishRequestResult: " + publishState + ", time=" + updatedTime);
                    mPublishHandler.onPublishStateChanged(publishState, updatedTime);
                    mPublishHandler.onPublishStateChanged(publishState, updatedTime, pidfXml);
                }
            };

@@ -371,9 +382,13 @@ public class PublishControllerImpl implements PublishController {
            publishCtrl.logd("handleMessage: " + EVENT_DESCRIPTION.get(message.what));
            switch (message.what) {
                case MSG_PUBLISH_STATE_CHANGED:
                    int newPublishState = message.arg1;
                    Instant updatedTimestamp = (Instant) message.obj;
                    publishCtrl.handlePublishStateChangedMessage(newPublishState, updatedTimestamp);
                    SomeArgs args = (SomeArgs) message.obj;
                    int newPublishState = (Integer) args.arg1;
                    Instant updatedTimestamp = (Instant) args.arg2;
                    String pidfXml = (String) args.arg3;
                    args.recycle();
                    publishCtrl.handlePublishStateChangedMessage(newPublishState, updatedTimestamp,
                            pidfXml);
                    break;

                case MSG_NOTIFY_CURRENT_PUBLISH_STATE:
@@ -414,11 +429,15 @@ public class PublishControllerImpl implements PublishController {
         * Send the message to notify the publish state is changed.
         */
        public void onPublishStateChanged(@PublishState int publishState,
                @NonNull Instant updatedTimestamp) {
                @NonNull Instant updatedTimestamp, String pidfXml) {
            Message message = obtainMessage();
            SomeArgs args = SomeArgs.obtain();
            args.arg1 = publishState;
            args.arg2 = updatedTimestamp;
            args.arg3 = pidfXml;

            message.what = MSG_PUBLISH_STATE_CHANGED;
            message.arg1 = publishState;
            message.obj = updatedTimestamp;
            message.obj = args;
            sendMessage(message);
        }

@@ -446,7 +465,7 @@ public class PublishControllerImpl implements PublishController {
            }
            if (publishCtrl.mIsDestroyedFlag) return;

            // Check if the PUBLISH request is allowed.
            // Return if the RCS capabilities presence uce is not enabled.
            if (!publishCtrl.isPublishRequestAllowed()) {
                publishCtrl.logd("requestPublish: SKIP. The publish request is not allowed.");
                publishCtrl.mPublishProcessor.setPendingRequest(true);
@@ -543,7 +562,7 @@ public class PublishControllerImpl implements PublishController {
     */
    private boolean isPublishRequestAllowed() {
        // The PUBLISH request requires that the RCS PRESENCE is capable.
        if (!mCapabilityPresenceEnabled) {
        if (!mDeviceCapabilityInfo.isPresenceCapable()) {
            logd("isPublishRequestAllowed: capability presence uce is not enabled.");
            return false;
        }
@@ -560,7 +579,7 @@ public class PublishControllerImpl implements PublishController {
     * from original state.
     */
    private void handlePublishStateChangedMessage(@PublishState int newPublishState,
            Instant updatedTimestamp) {
            Instant updatedTimestamp, String pidfXml) {
        synchronized (mPublishStateLock) {
            if (mIsDestroyedFlag) return;
            // Check if the time of the given publish state is not earlier than existing time.
@@ -575,6 +594,7 @@ public class PublishControllerImpl implements PublishController {
            if (mPublishState == newPublishState) return;
            mPublishState = newPublishState;
            mPublishStateUpdatedTime = updatedTimestamp;
            mPidfXml = pidfXml;
        }

        // Trigger the publish state changed in handler thread since it may take time.
@@ -660,12 +680,16 @@ public class PublishControllerImpl implements PublishController {
        pw.println("PublishControllerImpl" + "[subId: " + mSubId + "]:");
        pw.increaseIndent();

        pw.print("mCapabilityPresenceEnabled=");
        pw.println(mCapabilityPresenceEnabled);
        pw.print("isPresenceCapable=");
        pw.println(mDeviceCapabilityInfo.isPresenceCapable());
        pw.print("mPublishState=");
        pw.print(mPublishState);
        pw.print(" at time ");
        pw.println(mPublishStateUpdatedTime);
        pw.println("Last PIDF XML:");
        pw.increaseIndent();
        pw.println(mPidfXml);
        pw.decreaseIndent();

        if (mPublishProcessor != null) {
            mPublishProcessor.dump(pw);
+7 −3
Original line number Diff line number Diff line
@@ -210,7 +210,7 @@ public class PublishProcessor {

            // Generate a unique taskId to track this request.
            long taskId = mProcessorState.generatePublishTaskId();
            requestResponse = new PublishRequestResponse(mPublishCtrlCallback, taskId);
            requestResponse = new PublishRequestResponse(mPublishCtrlCallback, taskId, pidfXml);

            mLocalLog.log("publish capabilities: taskId=" + taskId);
            logi("publishCapabilities: taskId=" + taskId);
@@ -261,7 +261,9 @@ public class PublishProcessor {
            // Update the publish state if the request is failed and doesn't need to retry.
            int publishState = requestResponse.getPublishStateByCmdErrorCode();
            Instant responseTimestamp = requestResponse.getResponseTimestamp();
            mPublishCtrlCallback.updatePublishRequestResult(publishState, responseTimestamp);
            String pidfXml = requestResponse.getPidfXml();
            mPublishCtrlCallback.updatePublishRequestResult(publishState, responseTimestamp,
                    pidfXml);

            // Check if there is a pending request
            checkAndSendPendingRequest();
@@ -306,7 +308,9 @@ public class PublishProcessor {
            // Update the publish state if the request doesn't need to retry.
            int publishResult = requestResponse.getPublishStateByNetworkResponse();
            Instant responseTimestamp = requestResponse.getResponseTimestamp();
            mPublishCtrlCallback.updatePublishRequestResult(publishResult, responseTimestamp);
            String pidfXml = requestResponse.getPidfXml();
            mPublishCtrlCallback.updatePublishRequestResult(publishResult, responseTimestamp,
                    pidfXml);

            // Check if there is a pending request
            checkAndSendPendingRequest();
Loading