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

Commit f034e12b authored by Brad Ebinger's avatar Brad Ebinger
Browse files

Hidden SipTransport API definition

The SipTransport API definition, which is being put in using @hide
in order to allow applications to review and build testing around
the definitions.

In Follow up CLs, the APIs will be backed by the appropriate AIDLs
and will gradually start being moved to @SystemApi as they are
implemented and CTS tests are added

Test: CTS, docs review
Bug: 154763999
Change-Id: I5266eb7c077299c5e7a8c7780db6a30fffdfc556
parent 56804f05
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -128,13 +128,15 @@ public class ImsManager {
    }

    /**
     * Create an instance of SipDelegateManager for the subscription id specified.
     * Create an instance of {@link SipDelegateManager} for the subscription id specified.
     * <p>
     * Used for RCS single registration cases, where an IMS application needs to forward SIP
     * traffic through the device's IMS service.
     * @param subscriptionId The ID of the subscription that this SipDelegateManager will use.
     * Allows an IMS application to forward SIP traffic through the device's IMS service,
     * which is used for cellular carriers that require the device to share a single IMS
     * registration for both MMTEL and RCS features.
     * @param subscriptionId The ID of the subscription that this {@link SipDelegateManager} will
     *                       be bound to.
     * @throws IllegalArgumentException if the subscription is invalid.
     * @return a SipDelegateManager instance for the specified subscription ID.
     * @return a {@link SipDelegateManager} instance for the specified subscription ID.
     * @hide
     */
    @SystemApi
+59 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.telephony.ims;

import android.annotation.NonNull;
import android.telephony.ims.stub.SipDelegate;

/**
 * Callback interface provided to the SipTransport implementation to notify a remote application of
 * the following:
 * <ul>
 *     <li>A new incoming SIP message associated with the feature tags the SipDelegate registered
 *     with has been received or an in-dialog request to this SipDelegate has been received.</li>
 *     <li>Acknowledge that an outgoing SIP message from the RCS application has been sent
 *     successfully or notify the application of the reason why it was not sent</li>
 * </ul>
 * @hide
 */
public interface DelegateMessageCallback {

    /**
     * Send a new incoming SIP message to the remote application for processing.
     */
    void onMessageReceived(@NonNull SipMessage message);

    /**
     * Notify the remote application that a previous request to send a SIP message using
     * {@link SipDelegate#sendMessage} has succeeded.
     *
     * @param viaTransactionId The transaction ID found in the via header field of the
     *         previously sent {@link SipMessage}.
     */
    void onMessageSent(@NonNull String viaTransactionId);

    /**
     * Notify the remote application that a previous request to send a SIP message using
     * {@link SipDelegate#sendMessage} has failed.
     *
     * @param viaTransactionId The Transaction ID found in the via header field of the previously
     *         sent {@link SipMessage}.
     * @param reason The reason for the failure.
     */
    void onMessageSendFailure(@NonNull String viaTransactionId,
            @SipDelegateManager.MessageFailureReason int reason);
}
+327 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.telephony.ims;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArraySet;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * Contains the full state of the IMS feature tags associated with a SipDelegate and managed by the
 * ImsService.
 * @hide
 */
public final class DelegateRegistrationState implements Parcelable {

    /**
     * This feature tag has been deregistered for an unknown reason. Outgoing out-of-dialog SIP
     * messages associated with feature tags that are not registered will fail.
     */
    public static final int DEREGISTERED_REASON_UNKNOWN = 0;

    /**
     * This feature tag has been deregistered because it is not provisioned to be used on this radio
     * access technology or PDN. Outgoing out-of-dialog SIP messages associated with feature tags
     * that are not registered will fail.
     * <p>
     * There may be new incoming SIP dialog requests on a feature that that is not provisioned. It
     * is still expected that the SipDelegateConnection responds to the request.
     */
    public static final int DEREGISTERED_REASON_NOT_PROVISIONED = 1;

    /**
     * This feature tag has been deregistered because IMS has been deregistered. All outgoing SIP
     * messages will fail until IMS registration occurs.
     */
    public static final int DEREGISTERED_REASON_NOT_REGISTERED = 2;

    /**
     * This feature tag is being deregistered because the PDN that the IMS registration is on is
     *changing.
     * All open SIP dialogs need to be closed before the PDN change can proceed.
     */
    public static final int DEREGISTERING_REASON_PDN_CHANGE = 3;

    /**
     * This feature tag is being deregistered due to a provisioning change. This can be triggered by
     * many things, such as a provisioning change triggered by the carrier network, a radio access
     * technology change by the modem causing a different set of feature tags to be provisioned, or
     * a user triggered hange, such as data being enabled/disabled.
     * <p>
     * All open SIP dialogs associated with the new deprovisioned feature tag need to be closed
     * before the IMS registration modification can proceed.
     */
    public static final int DEREGISTERING_REASON_PROVISIONING_CHANGE = 4;

    /**
     * This feature tag is deregistering because the SipDelegate associated with this feature tag
     * needs to change its supported feature set.
     * <p>
     * All open SIP Dialogs associated with this feature tag must be closed before this operation
     * can proceed.
     */
    public static final int DEREGISTERING_REASON_FEATURE_TAGS_CHANGING = 5;

    /**
     * This feature tag is deregistering because the SipDelegate is in the process of being
     * destroyed.
     * <p>
     * All open SIP Dialogs associated with this feature tag must be closed before this operation
     * can proceed.
     */
    public static final int DEREGISTERING_REASON_DESTROY_PENDING = 6;

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = "DEREGISTERED_REASON_", value = {
            DEREGISTERED_REASON_UNKNOWN,
            DEREGISTERED_REASON_NOT_PROVISIONED,
            DEREGISTERED_REASON_NOT_REGISTERED
    })
    public @interface DeregisteredReason {}


    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = "DEREGISTERING_REASON_", value = {
            DEREGISTERING_REASON_PDN_CHANGE,
            DEREGISTERING_REASON_PROVISIONING_CHANGE,
            DEREGISTERING_REASON_FEATURE_TAGS_CHANGING,
            DEREGISTERING_REASON_DESTROY_PENDING
    })
    public @interface DeregisteringReason {}

    private final ArrayList<String> mRegisteredTags = new ArrayList<>();
    private final ArrayList<FeatureTagState> mDeregisteringTags = new ArrayList<>();
    private final ArrayList<FeatureTagState> mDeregisteredTags = new ArrayList<>();

    /**
     * Builder used to create new instances of {@link DelegateRegistrationState}.
     */
    public static class Builder {

        private final DelegateRegistrationState mState;

        /* Create a new instance of {@link Builder} */
        public Builder() {
            mState = new DelegateRegistrationState();
        }

        /**
         * Add a feature tag that is currently included in the current network IMS Registration.
         * @param featureTag The IMS media feature tag included in the current IMS registration.
         * @return The in-progress Builder instance for RegistrationState.
         */
        public Builder addRegisteredFeatureTag(@NonNull String featureTag) {
            if (!mState.mRegisteredTags.contains(featureTag)) {
                mState.mRegisteredTags.add(featureTag);
            }
            return this;
        }

        /**
         * Add a list of feature tags that are currently included in the current network IMS
         * Registration.
         * @param featureTags The IMS media feature tags included in the current IMS registration.
         * @return The in-progress Builder instance for RegistrationState.
         */
        public Builder addRegisteredFeatureTags(@NonNull Set<String> featureTags) {
            mState.mRegisteredTags.addAll(featureTags);
            return this;
        }

        /**
         * Add a feature tag that is in the current network IMS Registration, but is in the progress
         * of being deregistered and requires action from the RCS application before the IMS
         * registration can be modified.
         *
         * See {@link DeregisteringReason} for more information regarding what is required by the
         * RCS application to proceed.
         *
         * @param featureTag The media feature tag that has limited or no availability due to its
         *         current deregistering state.
         * @param reason The reason why the media feature tag has moved to the deregistering state.
         *         The availability of the feature tag depends on the {@link DeregisteringReason}.
         * @return The in-progress Builder instance for RegistrationState.
         */
        public Builder addDeregisteringFeatureTag(@NonNull String featureTag,
                @DeregisteringReason int reason) {
            boolean ftExists = mState.mDeregisteringTags.stream().anyMatch(
                    f -> f.getFeatureTag().equals(featureTag));
            if (!ftExists) {
                mState.mDeregisteringTags.add(new FeatureTagState(featureTag, reason));
            }
            return this;
        }

        /**
         * Add a feature tag that is currently not included in the network RCS registration. See
         * {@link DeregisteredReason} for more information regarding the reason for why the feature
         * tag is not registered.
         * @param featureTag The media feature tag that is not registered.
         * @param reason The reason why the media feature tag has been deregistered.
         * @return The in-progress Builder instance for RegistrationState.
         */
        public Builder addDeregisteredFeatureTag(@NonNull String featureTag,
                @DeregisteredReason int reason) {
            boolean ftExists = mState.mDeregisteredTags.stream().anyMatch(
                    f -> f.getFeatureTag().equals(featureTag));
            if (!ftExists) {
                mState.mDeregisteredTags.add(new FeatureTagState(featureTag, reason));
            }
            return this;
        }

        /**
         * @return the finalized instance.
         */
        public DelegateRegistrationState build() {
            return mState;
        }
    }

    /**
     * The builder should be used to construct a new instance of this class.
     */
    private DelegateRegistrationState() {}

    /**
     * Used for unparcelling only.
     */
    private DelegateRegistrationState(Parcel source) {
        source.readList(mRegisteredTags, null /*classloader*/);
        readStateFromParcel(source, mDeregisteringTags);
        readStateFromParcel(source, mDeregisteredTags);
    }

    /**
     * Get the feature tags that this SipDelegate is associated with that are currently part of the
     * network IMS registration. SIP Messages both in and out of a SIP Dialog may be sent and
     * received using these feature tags.
     * @return A Set of feature tags that the SipDelegate has associated with that are included in
     * the network IMS registration.
     */
    public @NonNull Set<String> getRegisteredFeatureTags() {
        return new ArraySet<>(mRegisteredTags);
    }

    /**
     * Get the feature tags that this SipDelegate is associated with that are currently part of the
     * network IMS registration but are in the process of being deregistered.
     * <p>
     * Any incoming SIP messages associated with a feature tag included in this list will still be
     * delivered. Outgoing SIP messages that are still in-dialog will be delivered to the
     * SipDelegate, but outgoing out-of-dialog SIP messages with  a feature tag that is included in
     * this list will fail.
     * <p>
     * The SipDelegate will stay in this state for a limited period of time while it waits for the
     * RCS application to perform a specific action. More details on the actions that can cause this
     * state as well as the expected response are included in the reason codes and can be found in
     * {@link DeregisteringReason}.
     * @return A Set of feature tags that the SipDelegate has associated with that are included in
     * the network IMS registration but are in the process of deregistering.
     */
    public @NonNull Set<FeatureTagState> getDeregisteringFeatureTags() {
        return new ArraySet<>(mDeregisteringTags);
    }

    /**
     * Get the list of feature tags that are associated with this SipDelegate but are not currently
     * included in the network IMS registration.
     * <p>
     * See {@link DeregisteredReason} codes for more information related to the reasons why this may
     * occur.
     * <p>
     * Due to network race conditions, there may still be onditions where an incoming out-of-dialog
     * SIP message is delivered for a feature tag that is considered deregistered. Due to this
     * condition, in-dialog outgoing SIP messages for deregistered feature tags will still be
     * allowed as long as they are in response to a dialog started by a remote party. Any outgoing
     * out-of-dialog SIP messages associated with feature tags included in this list will fail to be
     * sent.
     * @return A list of feature tags that the SipDelegate has associated with that not included in
     * the network IMS registration.
     */
    public @NonNull Set<FeatureTagState> getDeregisteredFeatureTags() {
        return new ArraySet<>(mDeregisteredTags);
    }

    public static final Creator<DelegateRegistrationState> CREATOR =
            new Creator<DelegateRegistrationState>() {
        @Override
        public DelegateRegistrationState createFromParcel(Parcel source) {
            return new DelegateRegistrationState(source);
        }

        @Override
        public DelegateRegistrationState[] newArray(int size) {
            return new DelegateRegistrationState[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeList(mRegisteredTags);
        writeStateToParcel(dest, mDeregisteringTags);
        writeStateToParcel(dest, mDeregisteredTags);
    }

    private void writeStateToParcel(Parcel dest, List<FeatureTagState> state) {
        dest.writeInt(state.size());
        for (FeatureTagState s : state) {
            dest.writeString(s.getFeatureTag());
            dest.writeInt(s.getState());
        }
    }

    private void readStateFromParcel(Parcel source, List<FeatureTagState> emptyState) {
        int len = source.readInt();
        for (int i = 0; i < len; i++) {
            String ft = source.readString();
            int reason = source.readInt();
            emptyState.add(new FeatureTagState(ft, reason));
        }
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        DelegateRegistrationState that = (DelegateRegistrationState) o;
        return mRegisteredTags.equals(that.mRegisteredTags)
                && mDeregisteringTags.equals(that.mDeregisteringTags)
                && mDeregisteredTags.equals(that.mDeregisteredTags);
    }

    @Override
    public int hashCode() {
        return Objects.hash(mRegisteredTags, mDeregisteringTags, mDeregisteredTags);
    }
}
+101 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.telephony.ims;

import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.ims.stub.SipDelegate;
import android.util.ArraySet;

import java.util.ArrayList;
import java.util.Objects;
import java.util.Set;

/**
 * Contains information required for the creation of a {@link SipDelegate} and the associated
 * SipDelegateConnection given back to the requesting application.
 * @hide
 */
public final class DelegateRequest implements Parcelable {

    private final ArrayList<String> mFeatureTags;

    /**
     * Create a new DelegateRequest, which will be used to create a SipDelegate by the ImsService.
     * @param featureTags The list of IMS feature tags that will be associated with the SipDelegate
     *                    created using this DelegateRequest. All feature tags are expected to be in
     *                    the format defined in RCC.07 section 2.6.1.3.
     */
    public DelegateRequest(@NonNull Set<String> featureTags) {
        if (featureTags == null) {
            throw new IllegalStateException("Invalid arguments, featureTags List can not be null");
        }
        mFeatureTags = new ArrayList<>(featureTags);
    }

    /**
     * @return the list of IMS feature tag associated with this DelegateRequest in the format
     * defined in RCC.07 section 2.6.1.3.
     */
    public Set<String> getFeatureTags() {
        return new ArraySet<>(mFeatureTags);
    }

    /**
     * Internal constructor used only for unparcelling.
     */
    private DelegateRequest(Parcel in) {
        mFeatureTags = new ArrayList<>();
        in.readList(mFeatureTags, null /*classLoader*/);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeList(mFeatureTags);
    }

    public static final @NonNull Creator<DelegateRequest> CREATOR = new Creator<DelegateRequest>() {
        @Override
        public DelegateRequest createFromParcel(Parcel source) {
            return new DelegateRequest(source);
        }

        @Override
        public DelegateRequest[] newArray(int size) {
            return new DelegateRequest[size];
        }
    };

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        DelegateRequest that = (DelegateRequest) o;
        return mFeatureTags.equals(that.mFeatureTags);
    }

    @Override
    public int hashCode() {
        return Objects.hash(mFeatureTags);
    }
}
+101 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading