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

Commit 4fa4e50a authored by Junho Yoon's avatar Junho Yoon Committed by Android (Google) Code Review
Browse files

Merge "Implement CallEndpoint representation and related APIs"

parents 5475ae53 edf3d826
Loading
Loading
Loading
Loading
+54 −10
Original line number Diff line number Diff line
@@ -41015,6 +41015,36 @@ package android.telecom {
    field public static final int ROUTE_WIRED_OR_EARPIECE = 5; // 0x5
  }
  public final class CallEndpoint implements android.os.Parcelable {
    ctor public CallEndpoint(@NonNull CharSequence, int, @NonNull android.os.ParcelUuid);
    method public int describeContents();
    method @NonNull public CharSequence getEndpointName();
    method public int getEndpointType();
    method @NonNull public android.os.ParcelUuid getIdentifier();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.telecom.CallEndpoint> CREATOR;
    field public static final int TYPE_BLUETOOTH = 2; // 0x2
    field public static final int TYPE_EARPIECE = 1; // 0x1
    field public static final int TYPE_SPEAKER = 4; // 0x4
    field public static final int TYPE_STREAMING = 5; // 0x5
    field public static final int TYPE_UNKNOWN = -1; // 0xffffffff
    field public static final int TYPE_WIRED_HEADSET = 3; // 0x3
  }
  public final class CallEndpointException extends java.lang.RuntimeException implements android.os.Parcelable {
    ctor public CallEndpointException(@Nullable String);
    ctor public CallEndpointException(@Nullable String, int);
    ctor public CallEndpointException(@Nullable String, int, @Nullable Throwable);
    method public int describeContents();
    method public int getCode();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.telecom.CallEndpointException> CREATOR;
    field public static final int ERROR_ANOTHER_REQUEST = 3; // 0x3
    field public static final int ERROR_ENDPOINT_DOES_NOT_EXIST = 1; // 0x1
    field public static final int ERROR_REQUEST_TIME_OUT = 2; // 0x2
    field public static final int ERROR_UNSPECIFIED = 4; // 0x4
  }
  public abstract class CallRedirectionService extends android.app.Service {
    ctor public CallRedirectionService();
    method public final void cancelCall();
@@ -41064,13 +41094,14 @@ package android.telecom {
    method public final boolean addConnection(android.telecom.Connection);
    method @NonNull public static android.telecom.Conference createFailedConference(@NonNull android.telecom.DisconnectCause, @NonNull android.telecom.PhoneAccountHandle);
    method public final void destroy();
    method public final android.telecom.CallAudioState getCallAudioState();
    method @Deprecated public final android.telecom.CallAudioState getCallAudioState();
    method public final java.util.List<android.telecom.Connection> getConferenceableConnections();
    method public final int getConnectionCapabilities();
    method public final int getConnectionProperties();
    method public final long getConnectionStartElapsedRealtimeMillis();
    method @IntRange(from=0) public final long getConnectionTime();
    method public final java.util.List<android.telecom.Connection> getConnections();
    method @NonNull public final android.telecom.CallEndpoint getCurrentCallEndpoint();
    method public final android.telecom.DisconnectCause getDisconnectCause();
    method public final android.os.Bundle getExtras();
    method public final android.telecom.PhoneAccountHandle getPhoneAccountHandle();
@@ -41081,13 +41112,16 @@ package android.telecom {
    method public final boolean isRingbackRequested();
    method public void onAddConferenceParticipants(@NonNull java.util.List<android.net.Uri>);
    method public void onAnswer(int);
    method public void onCallAudioStateChanged(android.telecom.CallAudioState);
    method public void onAvailableCallEndpointsChanged(@NonNull java.util.List<android.telecom.CallEndpoint>);
    method @Deprecated public void onCallAudioStateChanged(android.telecom.CallAudioState);
    method public void onCallEndpointChanged(@NonNull android.telecom.CallEndpoint);
    method public void onConnectionAdded(android.telecom.Connection);
    method public void onDisconnect();
    method public void onExtrasChanged(android.os.Bundle);
    method public void onHold();
    method public void onMerge(android.telecom.Connection);
    method public void onMerge();
    method public void onMuteStateChanged(boolean);
    method public void onPlayDtmfTone(char);
    method public void onReject();
    method public void onSeparate(android.telecom.Connection);
@@ -41130,7 +41164,7 @@ package android.telecom {
    method public final android.net.Uri getAddress();
    method public final int getAddressPresentation();
    method public final boolean getAudioModeIsVoip();
    method public final android.telecom.CallAudioState getCallAudioState();
    method @Deprecated public final android.telecom.CallAudioState getCallAudioState();
    method public final String getCallerDisplayName();
    method public final int getCallerDisplayNamePresentation();
    method public final int getCallerNumberVerificationStatus();
@@ -41138,6 +41172,7 @@ package android.telecom {
    method public final java.util.List<android.telecom.Conferenceable> getConferenceables();
    method public final int getConnectionCapabilities();
    method public final int getConnectionProperties();
    method @NonNull public final android.telecom.CallEndpoint getCurrentCallEndpoint();
    method public final android.telecom.DisconnectCause getDisconnectCause();
    method public final android.os.Bundle getExtras();
    method public final int getState();
@@ -41151,13 +41186,16 @@ package android.telecom {
    method public void onAddConferenceParticipants(@NonNull java.util.List<android.net.Uri>);
    method public void onAnswer(int);
    method public void onAnswer();
    method public void onCallAudioStateChanged(android.telecom.CallAudioState);
    method public void onAvailableCallEndpointsChanged(@NonNull java.util.List<android.telecom.CallEndpoint>);
    method @Deprecated public void onCallAudioStateChanged(android.telecom.CallAudioState);
    method public void onCallEndpointChanged(@NonNull android.telecom.CallEndpoint);
    method public void onCallEvent(String, android.os.Bundle);
    method public void onDeflect(android.net.Uri);
    method public void onDisconnect();
    method public void onExtrasChanged(android.os.Bundle);
    method public void onHandoverComplete();
    method public void onHold();
    method public void onMuteStateChanged(boolean);
    method public void onPlayDtmfTone(char);
    method public void onPostDialContinue(boolean);
    method public void onPullExternalCall();
@@ -41178,7 +41216,8 @@ package android.telecom {
    method public final void putExtras(@NonNull android.os.Bundle);
    method public final void removeExtras(java.util.List<java.lang.String>);
    method public final void removeExtras(java.lang.String...);
    method public void requestBluetoothAudio(@NonNull android.bluetooth.BluetoothDevice);
    method @Deprecated public void requestBluetoothAudio(@NonNull android.bluetooth.BluetoothDevice);
    method public final void requestCallEndpointChange(@NonNull android.telecom.CallEndpoint, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.telecom.CallEndpointException>);
    method public void sendConnectionEvent(String, android.os.Bundle);
    method public final void sendRemoteRttRequest();
    method public final void sendRttInitiationFailure(int);
@@ -41187,7 +41226,7 @@ package android.telecom {
    method public final void setActive();
    method public final void setAddress(android.net.Uri, int);
    method public final void setAudioModeIsVoip(boolean);
    method public final void setAudioRoute(int);
    method @Deprecated public final void setAudioRoute(int);
    method public final void setCallerDisplayName(String, int);
    method public final void setCallerNumberVerificationStatus(int);
    method public final void setConferenceableConnections(java.util.List<android.telecom.Connection>);
@@ -41439,18 +41478,23 @@ package android.telecom {
  public abstract class InCallService extends android.app.Service {
    ctor public InCallService();
    method public final boolean canAddCall();
    method public final android.telecom.CallAudioState getCallAudioState();
    method @Deprecated public final android.telecom.CallAudioState getCallAudioState();
    method public final java.util.List<android.telecom.Call> getCalls();
    method @NonNull public final android.telecom.CallEndpoint getCurrentCallEndpoint();
    method public void onAvailableCallEndpointsChanged(@NonNull java.util.List<android.telecom.CallEndpoint>);
    method public android.os.IBinder onBind(android.content.Intent);
    method public void onBringToForeground(boolean);
    method public void onCallAdded(android.telecom.Call);
    method public void onCallAudioStateChanged(android.telecom.CallAudioState);
    method @Deprecated public void onCallAudioStateChanged(android.telecom.CallAudioState);
    method public void onCallEndpointChanged(@NonNull android.telecom.CallEndpoint);
    method public void onCallRemoved(android.telecom.Call);
    method public void onCanAddCallChanged(boolean);
    method public void onConnectionEvent(android.telecom.Call, String, android.os.Bundle);
    method public void onMuteStateChanged(boolean);
    method public void onSilenceRinger();
    method public final void requestBluetoothAudio(@NonNull android.bluetooth.BluetoothDevice);
    method public final void setAudioRoute(int);
    method @Deprecated public final void requestBluetoothAudio(@NonNull android.bluetooth.BluetoothDevice);
    method public final void requestCallEndpointChange(@NonNull android.telecom.CallEndpoint, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.telecom.CallEndpointException>);
    method @Deprecated public final void setAudioRoute(int);
    method public final void setMuted(boolean);
    field public static final String SERVICE_INTERFACE = "android.telecom.InCallService";
  }
+22 −0
Original line number Diff line number Diff line
/*
 * Copyright 2022, 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.telecom;

/**
 * {@hide}
 */
parcelable CallEndpoint;
 No newline at end of file
+222 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.telecom;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.os.Parcel;
import android.os.ParcelUuid;
import android.os.Parcelable;
import android.text.TextUtils;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
import java.util.UUID;

/**
 * Encapsulates the endpoint where call media can flow
 */
public final class CallEndpoint implements Parcelable {
    /** @hide */
    public static final int ENDPOINT_OPERATION_SUCCESS = 0;
    /** @hide */
    public static final int ENDPOINT_OPERATION_FAILED = 1;

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({TYPE_UNKNOWN, TYPE_EARPIECE, TYPE_BLUETOOTH, TYPE_WIRED_HEADSET, TYPE_SPEAKER,
            TYPE_STREAMING})
    public @interface EndpointType {}

    /** Indicates that the type of endpoint through which call media flows is unknown type. */
    public static final int TYPE_UNKNOWN       = -1;

    /** Indicates that the type of endpoint through which call media flows is an earpiece. */
    public static final int TYPE_EARPIECE      = 1;

    /** Indicates that the type of endpoint through which call media flows is a Bluetooth. */
    public static final int TYPE_BLUETOOTH     = 2;

    /** Indicates that the type of endpoint through which call media flows is a wired headset. */
    public static final int TYPE_WIRED_HEADSET = 3;

    /** Indicates that the type of endpoint through which call media flows is a speakerphone. */
    public static final int TYPE_SPEAKER       = 4;

    /** Indicates that the type of endpoint through which call media flows is an external. */
    public static final int TYPE_STREAMING     = 5;

    private final CharSequence mName;
    private final int mType;
    private final ParcelUuid mIdentifier;

    /**
     * Constructor for a {@link CallEndpoint} object.
     *
     * @param name Human-readable name associated with the endpoint
     * @param type The type of endpoint through which call media being routed
     * Allowed values:
     * {@link #TYPE_EARPIECE}
     * {@link #TYPE_BLUETOOTH}
     * {@link #TYPE_WIRED_HEADSET}
     * {@link #TYPE_SPEAKER}
     * {@link #TYPE_STREAMING}
     * {@link #TYPE_UNKNOWN}
     * @param id A unique identifier for this endpoint on the device
     */
    public CallEndpoint(@NonNull CharSequence name, @EndpointType int type,
            @NonNull ParcelUuid id) {
        this.mName = name;
        this.mType = type;
        this.mIdentifier = id;
    }

    /** @hide */
    public CallEndpoint(@NonNull CharSequence name, @EndpointType int type) {
        this(name, type, new ParcelUuid(UUID.randomUUID()));
    }

    /** @hide */
    public CallEndpoint(CallEndpoint endpoint) {
        mName = endpoint.getEndpointName();
        mType = endpoint.getEndpointType();
        mIdentifier = endpoint.getIdentifier();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof CallEndpoint)) {
            return false;
        }
        CallEndpoint endpoint = (CallEndpoint) obj;
        return getEndpointName().toString().contentEquals(endpoint.getEndpointName())
                && getEndpointType() == endpoint.getEndpointType()
                && getIdentifier().equals(endpoint.getIdentifier());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode() {
        return Objects.hash(mName, mType, mIdentifier);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return TextUtils.formatSimple("[CallEndpoint Name: %s, Type: %s, Identifier: %s]",
                mName.toString(), endpointTypeToString(mType), mIdentifier.toString());
    }

    /**
     * @return Human-readable name associated with the endpoint
     */
    @NonNull
    public CharSequence getEndpointName() {
        return mName;
    }

    /**
     * @return The type of endpoint through which call media being routed
     */
    @EndpointType
    public int getEndpointType() {
        return mType;
    }

    /**
     * @return A unique identifier for this endpoint on the device
     */
    @NonNull
    public ParcelUuid getIdentifier() {
        return mIdentifier;
    }

    /**
     * Converts the provided endpoint type into a human-readable string representation.
     *
     * @param endpointType to convert into a string.
     * @return String representation of the provided endpoint type.
     * @hide
     */
    @NonNull
    public static String endpointTypeToString(int endpointType) {
        switch (endpointType) {
            case TYPE_EARPIECE:
                return "EARPIECE";
            case TYPE_BLUETOOTH:
                return "BLUETOOTH";
            case TYPE_WIRED_HEADSET:
                return "WIRED_HEADSET";
            case TYPE_SPEAKER:
                return "SPEAKER";
            case TYPE_STREAMING:
                return "EXTERNAL";
            default:
                return "UNKNOWN (" + endpointType + ")";
        }
    }

    /**
     * Responsible for creating CallEndpoint objects for deserialized Parcels.
     */
    public static final @android.annotation.NonNull Parcelable.Creator<CallEndpoint> CREATOR =
            new Parcelable.Creator<CallEndpoint>() {

        @Override
        public CallEndpoint createFromParcel(Parcel source) {
            CharSequence name = source.readCharSequence();
            int type = source.readInt();
            ParcelUuid id = ParcelUuid.CREATOR.createFromParcel(source);

            return new CallEndpoint(name, type, id);
        }

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

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

    /**
     * {@inheritDoc}
     */
    @Override
    public void writeToParcel(@NonNull Parcel destination, int flags) {
        destination.writeCharSequence(mName);
        destination.writeInt(mType);
        mIdentifier.writeToParcel(destination, flags);
    }
}
+22 −0
Original line number Diff line number Diff line
/*
 * Copyright 2022, 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.telecom;

/**
 * {@hide}
 */
parcelable CallEndpointException;
 No newline at end of file
+130 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.telecom;

import android.annotation.IntDef;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;

import androidx.annotation.NonNull;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * This class represents a set of exceptions that can occur when requesting a
 * {@link CallEndpoint} change.
 */
public final class CallEndpointException extends RuntimeException implements Parcelable {
    /** @hide */
    public static final String CHANGE_ERROR = "ChangeErrorKey";

    /**
     * The operation has failed because requested CallEndpoint does not exist.
     */
    public static final int ERROR_ENDPOINT_DOES_NOT_EXIST = 1;

    /**
     * The operation was not completed on time.
     */
    public static final int ERROR_REQUEST_TIME_OUT = 2;

    /**
     * The operation was canceled by another request.
     */
    public static final int ERROR_ANOTHER_REQUEST = 3;

    /**
     * The operation has failed due to an unknown or unspecified error.
     */
    public static final int ERROR_UNSPECIFIED = 4;

    private int mCode = ERROR_UNSPECIFIED;
    private final String mMessage;

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

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeString8(mMessage);
        dest.writeInt(mCode);
    }

    /**
     * Responsible for creating CallEndpointException objects for deserialized Parcels.
     */
    public static final @android.annotation.NonNull Parcelable.Creator<CallEndpointException>
            CREATOR = new Parcelable.Creator<>() {
                @Override
                public CallEndpointException createFromParcel(Parcel source) {
                    return new CallEndpointException(source.readString8(), source.readInt());
                }

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

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({ERROR_ENDPOINT_DOES_NOT_EXIST, ERROR_REQUEST_TIME_OUT, ERROR_ANOTHER_REQUEST,
            ERROR_UNSPECIFIED})
    public @interface CallEndpointErrorCode {
    }

    public CallEndpointException(@Nullable String message) {
        super(getMessage(message, ERROR_UNSPECIFIED));
        mMessage = message;
    }

    public CallEndpointException(@Nullable String message, @CallEndpointErrorCode int code) {
        super(getMessage(message, code));
        mCode = code;
        mMessage = message;
    }

    public CallEndpointException(@Nullable String message, @CallEndpointErrorCode int code,
            @Nullable Throwable cause) {
        super(getMessage(message, code), cause);
        mCode = code;
        mMessage = message;
    }


    public @CallEndpointErrorCode int getCode() {
        return mCode;
    }

    private static String getMessage(String message, int code) {
        StringBuilder builder;
        if (!TextUtils.isEmpty(message)) {
            builder = new StringBuilder(message);
            builder.append(" (code: ");
            builder.append(code);
            builder.append(")");
            return builder.toString();
        } else {
            return "code: " + code;
        }
    }
}
Loading