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

Commit 394eb901 authored by Hyunho's avatar Hyunho
Browse files

ims rcs api improvement - add onPublishUpdated api

Bug: b/203406296
Test: atest PublishControllerImplTest PublishProcessorTest.
Change-Id: Ic0597ba3e3febe917272c2df91fc13621632af7f
Merged-In: Ic0597ba3e3febe917272c2df91fc13621632af7f
parent eb404b14
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -89,6 +89,16 @@ public class RcsFeatureManager implements FeatureUpdates {
         */
        void onUnpublish();

        /**
         * Notify the framework that the ImsService has refreshed the PUBLISH
         * internally, which has resulted in a new PUBLISH result.
         * <p>
         * This method must return both SUCCESS (200 OK) and FAILURE (300+) codes in order to
         * keep the AOSP stack up to date.
         */
        void onPublishUpdated(int reasonCode, String reasonPhrase,
                int reasonHeaderCause, String reasonHeaderText);

        /**
         * Receive a capabilities request from the remote client.
         */
@@ -112,6 +122,13 @@ public class RcsFeatureManager implements FeatureUpdates {
                    mCapabilityEventCallback.forEach(callback -> callback.onUnpublish());
                }

                @Override
                public void onPublishUpdated(int reasonCode, String reasonPhrase,
                        int reasonHeaderCause, String reasonHeaderText) {
                    mCapabilityEventCallback.forEach(callback -> callback.onPublishUpdated(
                            reasonCode, reasonPhrase, reasonHeaderCause, reasonHeaderText));
                }

                @Override
                public void onRemoteCapabilityRequest(Uri contactUri,
                        List<String> remoteCapabilities, IOptionsRequestCallback cb) {
+59 −4
Original line number Diff line number Diff line
@@ -200,11 +200,13 @@ public class UceController {
    private static class CachedCapabilityEvent {
        private Optional<Integer> mRequestPublishCapabilitiesEvent;
        private Optional<Boolean> mUnpublishEvent;
        private Optional<SomeArgs> mPublishUpdatedEvent;
        private Optional<SomeArgs> mRemoteCapabilityRequestEvent;

        public CachedCapabilityEvent() {
            mRequestPublishCapabilitiesEvent = Optional.empty();
            mUnpublishEvent = Optional.empty();
            mPublishUpdatedEvent = Optional.empty();
            mRemoteCapabilityRequestEvent = Optional.empty();
        }

@@ -222,6 +224,19 @@ public class UceController {
            mUnpublishEvent = Optional.of(Boolean.TRUE);
        }

        /**
         * Cache the publish update event triggered by the ImsService.
         */
        public synchronized void setOnPublishUpdatedEvent(int reasonCode, String reasonPhrase,
                int reasonHeaderCause, String reasonHeaderText) {
            SomeArgs args = SomeArgs.obtain();
            args.arg1 = reasonCode;
            args.arg2 = reasonPhrase;
            args.arg3 = reasonHeaderCause;
            args.arg4 = reasonHeaderText;
            mPublishUpdatedEvent = Optional.of(args);
        }

        /**
         * Cache the remote capability request event triggered by the ImsService.
         */
@@ -244,6 +259,11 @@ public class UceController {
            return mUnpublishEvent;
        }

        /** @Return the cached pubilsh update event */
        public synchronized Optional<SomeArgs> getPublishUpdatedEvent() {
            return mPublishUpdatedEvent;
        }

        /** @Return the cached remote capability request event */
        public synchronized Optional<SomeArgs> getRemoteCapabilityRequestEvent() {
            return mRemoteCapabilityRequestEvent;
@@ -253,6 +273,8 @@ public class UceController {
        public synchronized void clear() {
            mRequestPublishCapabilitiesEvent = Optional.empty();
            mUnpublishEvent = Optional.empty();
            mPublishUpdatedEvent.ifPresent(args -> args.recycle());
            mPublishUpdatedEvent = Optional.empty();
            mRemoteCapabilityRequestEvent.ifPresent(args -> args.recycle());
            mRemoteCapabilityRequestEvent = Optional.empty();
        }
@@ -455,6 +477,15 @@ public class UceController {
        Optional<Boolean> unpublishEvent = mCachedCapabilityEvent.getUnpublishEvent();
        unpublishEvent.ifPresent(unpublish -> onUnpublish());

        Optional<SomeArgs> publishUpdatedEvent = mCachedCapabilityEvent.getPublishUpdatedEvent();
        publishUpdatedEvent.ifPresent(args -> {
            int reasonCode = (Integer) args.arg1;
            String reasonPhrase = (String) args.arg2;
            int reasonHeaderCause = (Integer) args.arg3;
            String reasonHeaderText = (String) args.arg4;
            onPublishUpdated(reasonCode, reasonPhrase, reasonHeaderCause, reasonHeaderText);
        });

        Optional<SomeArgs> remoteRequest = mCachedCapabilityEvent.getRemoteCapabilityRequestEvent();
        remoteRequest.ifPresent(args -> {
            Uri contactUri = (Uri) args.arg1;
@@ -552,6 +583,18 @@ public class UceController {
                    UceController.this.onUnpublish();
                }

                @Override
                public void onPublishUpdated(int reasonCode, String reasonPhrase,
                        int reasonHeaderCause, String reasonHeaderText) {
                    if (isRcsConnecting()) {
                        mCachedCapabilityEvent.setOnPublishUpdatedEvent(reasonCode, reasonPhrase,
                                reasonHeaderCause, reasonHeaderText);
                        return;
                    }
                    UceController.this.onPublishUpdated(reasonCode, reasonPhrase,
                            reasonHeaderCause, reasonHeaderText);
                }

                @Override
                public void onRemoteCapabilityRequest(Uri contactUri,
                        List<String> remoteCapabilities, IOptionsRequestCallback cb) {
@@ -671,6 +714,17 @@ public class UceController {
        mPublishController.onUnpublish();
    }

    /**
     * This method is triggered by the ImsService to notify framework that the device's
     * publish status has been changed.
     */
    public void onPublishUpdated(int reasonCode, String reasonPhrase,
            int reasonHeaderCause, String reasonHeaderText) {
        logi("onPublishUpdated");
        mPublishController.onPublishUpdated(reasonCode, reasonPhrase,
                reasonHeaderCause, reasonHeaderText);
    }

    /**
     * Request publish the device's capabilities. This request is from the ImsService to send the
     * capabilities to the remote side.
@@ -684,8 +738,9 @@ public class UceController {
    /**
     * Register a {@link PublishStateCallback} to receive the published state changed.
     */
    public void registerPublishStateCallback(@NonNull IRcsUcePublishStateCallback c) {
        mPublishController.registerPublishStateCallback(c);
    public void registerPublishStateCallback(@NonNull IRcsUcePublishStateCallback c,
            boolean supportPublishingState) {
        mPublishController.registerPublishStateCallback(c, supportPublishingState);
    }

    /**
@@ -698,8 +753,8 @@ public class UceController {
    /**
     * Get the UCE publish state if the PUBLISH is supported by the carrier.
     */
    public @PublishState int getUcePublishState() {
        return mPublishController.getUcePublishState();
    public @PublishState int getUcePublishState(boolean isSupportPublishingState) {
        return mPublishController.getUcePublishState(isSupportPublishingState);
    }

    /**
+14 −2
Original line number Diff line number Diff line
@@ -149,6 +149,11 @@ public interface PublishController extends ControllerBase {
         * Update the device state with the publish request result.
         */
        void refreshDeviceState(int SipCode, String reason);

        /**
         * Sent the publish request to ImsService.
         */
        void notifyPendingPublishRequest();
    }

    /**
@@ -183,7 +188,7 @@ public interface PublishController extends ControllerBase {
    /**
     * Retrieve the RCS UCE Publish state.
     */
    @PublishState int getUcePublishState();
    @PublishState int getUcePublishState(boolean isSupportPublishingState);

    /**
     * @return the last PIDF XML used for publish or {@code null} if the device is not published.
@@ -195,6 +200,12 @@ public interface PublishController extends ControllerBase {
     */
    void onUnpublish();

    /**
     * Notify that the device's publish status have been changed.
     */
    void onPublishUpdated(int reasonCode, String reasonPhrase,
            int reasonHeaderCause, String reasonHeaderText);

    /**
     * Retrieve the device's capabilities.
     */
@@ -208,7 +219,8 @@ public interface PublishController extends ControllerBase {
    /**
     * Register a {@link PublishStateCallback} to listen to the published state changed.
     */
    void registerPublishStateCallback(@NonNull IRcsUcePublishStateCallback c);
    void registerPublishStateCallback(@NonNull IRcsUcePublishStateCallback c,
            boolean supportPublishingState);

    /**
     * Removes an existing {@link PublishStateCallback}.
+174 −21
Original line number Diff line number Diff line
@@ -97,7 +97,12 @@ public class PublishControllerImpl implements PublishController {
    // The capability type that the device is using.
    private @RcsImsCapabilityFlag int mCapabilityType;
    // The device publish state
    private @PublishState int mPublishState;
    @VisibleForTesting
    public @PublishState int mLastPublishState;
    // The device publish state to support the newly added publish state
    @VisibleForTesting
    public @PublishState int mCurrentPublishState;

    // The timestamp of updating the publish state
    private Instant mPublishStateUpdatedTime = Instant.now();
    // The last PIDF XML used in the publish
@@ -105,7 +110,6 @@ public class PublishControllerImpl implements PublishController {

    // The callbacks to notify publish state changed.
    private RemoteCallbackList<IRcsUcePublishStateCallback> mPublishStateCallbacks;

    private final Object mPublishStateLock = new Object();

    // The information of the device's capabilities.
@@ -165,7 +169,8 @@ public class PublishControllerImpl implements PublishController {

    private void initPublishController(Looper looper) {
        mCapabilityType = PublishUtils.getCapabilityType(mContext, mSubId);
        mPublishState = getInitialPublishState(mCapabilityType);
        mCurrentPublishState = getInitialPublishState(mCapabilityType);
        mLastPublishState = mCurrentPublishState;
        mPublishStateCallbacks = new RemoteCallbackList<>();
        mPublishHandler = new PublishHandler(this, looper);

@@ -179,7 +184,7 @@ public class PublishControllerImpl implements PublishController {
        mDeviceCapListener.initialize();

        logd("initPublishController completed: capabilityType=" + mCapabilityType +
                ", publishState=" + mPublishState);
                ", publishState=" + mCurrentPublishState);
    }

    /**
@@ -234,9 +239,21 @@ public class PublishControllerImpl implements PublishController {
    }

    @Override
    public int getUcePublishState() {
    public int getUcePublishState(boolean isSupportPublishingState) {
        synchronized (mPublishStateLock) {
            return (!mIsDestroyedFlag) ? mPublishState : RcsUceAdapter.PUBLISH_STATE_OTHER_ERROR;
            if (mIsDestroyedFlag) {
                return RcsUceAdapter.PUBLISH_STATE_OTHER_ERROR;
            }
            if (isSupportPublishingState) {
                // in that case, the caller is support Build.VERSION_CODES.S
                // return the current state that is including newly added publishing state.
                return mCurrentPublishState;
            } else {
                if (mCurrentPublishState == RcsUceAdapter.PUBLISH_STATE_PUBLISHING) {
                    return mLastPublishState;
                }
                return mCurrentPublishState;
            }
        }
    }

@@ -282,15 +299,16 @@ public class PublishControllerImpl implements PublishController {
     * Register a {@link PublishStateCallback} to listen to the published state changed.
     */
    @Override
    public void registerPublishStateCallback(@NonNull IRcsUcePublishStateCallback c) {
    public void registerPublishStateCallback(@NonNull IRcsUcePublishStateCallback c,
            boolean supportPublishingState) {
        synchronized (mPublishStateLock) {
            if (mIsDestroyedFlag) return;
            mPublishStateCallbacks.register(c);
            mPublishStateCallbacks.register(c, new Boolean(supportPublishingState));
            logd("registerPublishStateCallback: size="
                    + mPublishStateCallbacks.getRegisteredCallbackCount());
        }
        // Notify the current publish state
        mPublishHandler.sendNotifyCurrentPublishStateMessage(c);
        mPublishHandler.sendNotifyCurrentPublishStateMessage(c, supportPublishingState);
    }

    /**
@@ -301,6 +319,8 @@ public class PublishControllerImpl implements PublishController {
        synchronized (mPublishStateLock) {
            if (mIsDestroyedFlag) return;
            mPublishStateCallbacks.unregister(c);
            logd("unregisterPublishStateCallback:mPublishStateCallbacks: size="
                    + mPublishStateCallbacks.getRegisteredCallbackCount());
        }
    }

@@ -339,6 +359,17 @@ public class PublishControllerImpl implements PublishController {
        mPublishHandler.sendUnpublishedMessage(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED);
    }

    /**
     * Notify that the device's publish status have been changed.
     */
    @Override
    public void onPublishUpdated(int reasonCode, String reasonPhrase,
            int reasonHeaderCause, String reasonHeaderText) {
        if (mIsDestroyedFlag) return;
        mPublishHandler.sendPublishUpdatedMessage(reasonCode, reasonPhrase, reasonHeaderCause,
                reasonHeaderText);
    }

    @Override
    public RcsContactUceCapability getDeviceCapabilities(@CapabilityMechanism int mechanism) {
        return mDeviceCapabilityInfo.getDeviceCapabilities(mechanism, mContext);
@@ -397,6 +428,12 @@ public class PublishControllerImpl implements PublishController {
                    mUceCtrlCallback.refreshDeviceState(sipCode, reason,
                            UceController.REQUEST_TYPE_PUBLISH);
                }

                @Override
                public void notifyPendingPublishRequest() {
                    logd("notifyPendingPublishRequest");
                    mPublishHandler.sendPublishSentMessage();
                }
            };

    /**
@@ -422,6 +459,8 @@ public class PublishControllerImpl implements PublishController {
        private static final int MSG_REQUEST_CANCELED = 11;
        private static final int MSG_RESET_DEVICE_STATE = 12;
        private static final int MSG_UNPUBLISHED = 13;
        private static final int MSG_PUBLISH_SENT = 14;
        private static final int MSG_PUBLISH_UPDATED = 15;

        private final WeakReference<PublishControllerImpl> mPublishControllerRef;

@@ -475,7 +514,11 @@ public class PublishControllerImpl implements PublishController {
                }
                case MSG_NOTIFY_CURRENT_PUBLISH_STATE:
                    IRcsUcePublishStateCallback c = (IRcsUcePublishStateCallback) message.obj;
                    publishCtrl.handleNotifyCurrentPublishStateMessage(c);
                    boolean supportPublishingState = false;
                    if (message.arg1 == 1) {
                        supportPublishingState = true;
                    }
                    publishCtrl.handleNotifyCurrentPublishStateMessage(c, supportPublishingState);
                    break;

                case MSG_REQUEST_PUBLISH:
@@ -510,6 +553,22 @@ public class PublishControllerImpl implements PublishController {
                    publishCtrl.handleUnpublishedMessage(newPublishState, updatedTimestamp);
                    break;
                }

                case MSG_PUBLISH_SENT:
                    publishCtrl.handlePublishSentMessage();
                    break;

                case MSG_PUBLISH_UPDATED: {
                    SomeArgs args = (SomeArgs) message.obj;
                    int reasonCode = (Integer) args.arg1;
                    String reasonPhrase = (String) args.arg2;
                    int reasonHeaderCause = (Integer) args.arg3;
                    String reasonHeaderText = (String) args.arg4;
                    args.recycle();
                    publishCtrl.handlePublishUpdatedMessage(reasonCode, reasonPhrase,
                            reasonHeaderCause, reasonHeaderText);
                    break;
                }
                default:
                    publishCtrl.logd("invalid message: " + message.what);
                    break;
@@ -613,21 +672,55 @@ public class PublishControllerImpl implements PublishController {
            message.obj = args;
            sendMessage(message);
        }

        /**
         * Send the message to notify the publish state is changed.
         */
        public void sendPublishUpdatedMessage(int reasonCode, String reasonPhrase,
                int reasonHeaderCause, String reasonHeaderText) {
            PublishControllerImpl publishCtrl = mPublishControllerRef.get();
            if (publishCtrl == null) return;
            if (publishCtrl.mIsDestroyedFlag) return;

            SomeArgs args = SomeArgs.obtain();
            args.arg1 = reasonCode;
            args.arg2 = reasonPhrase;
            args.arg3 = reasonHeaderCause;
            args.arg4 = reasonHeaderText;
            Message message = obtainMessage();
            message.what = MSG_PUBLISH_UPDATED;
            message.obj = args;
            sendMessage(message);
        }

        /**
         * Send the message to notify the new added callback of the latest publish state.
         */
        public void sendNotifyCurrentPublishStateMessage(
                IRcsUcePublishStateCallback callback) {
                IRcsUcePublishStateCallback callback, boolean supportPublishingState) {
            PublishControllerImpl publishCtrl = mPublishControllerRef.get();
            if (publishCtrl == null) return;
            if (publishCtrl.mIsDestroyedFlag) return;

            Message message = obtainMessage();
            message.what = MSG_NOTIFY_CURRENT_PUBLISH_STATE;
            message.arg1 = supportPublishingState ? 1 : 0;
            message.obj = callback;
            sendMessage(message);
        }

        /**
         * Send the message that the publish request has been sent to the ImsService.
         */
        public void sendPublishSentMessage() {
            PublishControllerImpl publishCtrl = mPublishControllerRef.get();
            if (publishCtrl == null) return;
            if (publishCtrl.mIsDestroyedFlag) return;
            Message message = obtainMessage();
            message.what = MSG_PUBLISH_SENT;
            sendMessage(message);
        }

        public void sendPublishMessage(@PublishTriggerType int type) {
            sendPublishMessage(type, 0L);
        }
@@ -734,6 +827,8 @@ public class PublishControllerImpl implements PublishController {
            EVENT_DESCRIPTION.put(MSG_REQUEST_CANCELED, "REQUEST_CANCELED");
            EVENT_DESCRIPTION.put(MSG_RESET_DEVICE_STATE, "RESET_DEVICE_STATE");
            EVENT_DESCRIPTION.put(MSG_UNPUBLISHED, "MSG_UNPUBLISHED");
            EVENT_DESCRIPTION.put(MSG_PUBLISH_SENT, "MSG_PUBLISH_SENT");
            EVENT_DESCRIPTION.put(MSG_PUBLISH_UPDATED, "MSG_PUBLISH_UPDATED");
        }
    }

@@ -932,23 +1027,24 @@ public class PublishControllerImpl implements PublishController {
                        + ", publishState=" + newPublishState);
                return;
            }
            logd("publish state changes from " + mPublishState + " to " + newPublishState +
            logd("publish state changes from " + mCurrentPublishState + " to " + newPublishState +
                    ", time=" + updatedTimestamp);
            mPublishStateUpdatedTime = updatedTimestamp;
            mPidfXml = pidfXml;
            // Bail early and do not update listeners if the publish state didn't change.
            if (mPublishState == newPublishState) return;
            mPublishState = newPublishState;
            if (mCurrentPublishState == newPublishState) return;
            mLastPublishState = mCurrentPublishState;
            mCurrentPublishState = newPublishState;
        }
        if (newPublishState == RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED) {
            mUceStatsWriter.setUnPublish(mSubId);
        }

        // Trigger the publish state changed in handler thread since it may take time.
        logd("Notify publish state changed: " + mPublishState);
        logd("Notify publish state changed: " + mCurrentPublishState);
        mPublishStateCallbacks.broadcast(c -> {
            try {
                c.onPublishStateChanged(mPublishState);
                c.onPublishStateChanged(mCurrentPublishState);
            } catch (RemoteException e) {
                logw("Notify publish state changed error: " + e);
            }
@@ -956,10 +1052,11 @@ public class PublishControllerImpl implements PublishController {
        logd("Notify publish state changed: completed");
    }

    private void handleNotifyCurrentPublishStateMessage(IRcsUcePublishStateCallback callback) {
    private void handleNotifyCurrentPublishStateMessage(IRcsUcePublishStateCallback callback,
            boolean supportPublishingState) {
        if (mIsDestroyedFlag || callback == null) return;
        try {
            callback.onPublishStateChanged(getUcePublishState());
            callback.onPublishStateChanged(getUcePublishState(supportPublishingState));
        } catch (RemoteException e) {
            logw("handleCurrentPublishStateUpdateMessage exception: " + e);
        }
@@ -1029,10 +1126,64 @@ public class PublishControllerImpl implements PublishController {
        handlePublishStateChangedMessage(newPublishState, updatedTimestamp, null);
    }

    private void handlePublishSentMessage() {
        synchronized (mPublishStateLock) {
            if (mIsDestroyedFlag) return;
            int lastIndex = mPublishStateCallbacks.getRegisteredCallbackCount() - 1;
            int tempPublishState = mCurrentPublishState;
            for (int index = lastIndex; index >= 0; index--) {
                IRcsUcePublishStateCallback callback =
                        mPublishStateCallbacks.getRegisteredCallbackItem(index);
                boolean isSupportPublishingState = false;
                try {
                    Object object = mPublishStateCallbacks.getRegisteredCallbackCookie(index);
                    if (object != null) {
                        isSupportPublishingState = (Boolean) object;
                    }
                } catch (Exception e) {
                    // Do not handle the exception
                }
                try {
                    mCurrentPublishState = RcsUceAdapter.PUBLISH_STATE_PUBLISHING;
                    if (isSupportPublishingState) {
                        if (callback != null) {
                            callback.onPublishStateChanged(mCurrentPublishState);
                        }
                    } else {
                        // If it is currently PUBLISH_STATE_OK, the state must not be changed to
                        // PUBLISH_STATE_NOT_PUBLISHED.
                        // And in the case of the current PUBLISH_STATE_NOT_PUBLISHED, it is
                        // necessary to avoid reporting the duplicate state.
                        if (tempPublishState != RcsUceAdapter.PUBLISH_STATE_OK
                                && tempPublishState != RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED) {
                            // set the state to PUBLISH_STATE_NOT_PUBLISHED so that
                            // getUcePublishState is consistent with the callback
                            mLastPublishState = RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED;
                            if (callback != null) {
                                callback.onPublishStateChanged(mLastPublishState);
                            }
                        }
                    }
                } catch (RemoteException e) {
                    logw("Notify publish state changed error: " + e);
                }
            }
        }
    }

    private void handlePublishUpdatedMessage(int reasonCode, String reasonPhrase,
            int reasonHeaderCause, String reasonHeaderText) {
        if (mIsDestroyedFlag) return;
        PublishRequestResponse updatedPublish = new PublishRequestResponse(getLastPidfXml(),
                reasonCode, reasonPhrase, reasonHeaderCause, reasonHeaderText);
        mPublishProcessor.publishUpdated(updatedPublish);
    }

    @VisibleForTesting
    public void setCapabilityType(int type) {
        mCapabilityType = type;
        mPublishState = getInitialPublishState(mCapabilityType);
        mCurrentPublishState = getInitialPublishState(mCapabilityType);
        mLastPublishState = mCurrentPublishState;
    }

    @VisibleForTesting
@@ -1085,8 +1236,10 @@ public class PublishControllerImpl implements PublishController {

        pw.print("isPresenceCapable=");
        pw.println(mDeviceCapabilityInfo.isPresenceCapable());
        pw.print("mPublishState=");
        pw.print(mPublishState);
        pw.print("mCurrentPublishState=");
        pw.print(mCurrentPublishState);
        pw.print("mLastPublishState=");
        pw.print(mLastPublishState);
        pw.print(" at time ");
        pw.println(mPublishStateUpdatedTime);
        pw.println("Last PIDF XML:");
+28 −10

File changed.

Preview size limit exceeded, changes collapsed.

Loading