Merge "Add API for cross device calling."
This commit is contained in:
@@ -40538,6 +40538,7 @@ package android.telecom {
|
||||
public final class Call {
|
||||
method public void addConferenceParticipants(@NonNull java.util.List<android.net.Uri>);
|
||||
method public void answer(int);
|
||||
method public void answerCall(@NonNull android.telecom.CallEndpoint, int);
|
||||
method public void conference(android.telecom.Call);
|
||||
method public void deflect(android.net.Uri);
|
||||
method public void disconnect();
|
||||
@@ -40558,7 +40559,9 @@ package android.telecom {
|
||||
method public void phoneAccountSelected(android.telecom.PhoneAccountHandle, boolean);
|
||||
method public void playDtmfTone(char);
|
||||
method public void postDialContinue(boolean);
|
||||
method public void pullExternalCall();
|
||||
method public void pullCall();
|
||||
method @Deprecated public void pullExternalCall();
|
||||
method public void pushCall(@NonNull android.telecom.CallEndpoint);
|
||||
method public void putExtras(android.os.Bundle);
|
||||
method public void registerCallback(android.telecom.Call.Callback);
|
||||
method public void registerCallback(android.telecom.Call.Callback, android.os.Handler);
|
||||
@@ -40601,7 +40604,10 @@ package android.telecom {
|
||||
|
||||
public abstract static class Call.Callback {
|
||||
ctor public Call.Callback();
|
||||
method public void onAnswerFailed(@NonNull android.telecom.CallEndpoint, int);
|
||||
method public void onCallDestroyed(android.telecom.Call);
|
||||
method public void onCallPullFailed(int);
|
||||
method public void onCallPushFailed(@NonNull android.telecom.CallEndpoint, int);
|
||||
method public void onCannedTextResponsesLoaded(android.telecom.Call, java.util.List<java.lang.String>);
|
||||
method public void onChildrenChanged(android.telecom.Call, java.util.List<android.telecom.Call>);
|
||||
method public void onConferenceableCallsChanged(android.telecom.Call, java.util.List<android.telecom.Call>);
|
||||
@@ -40617,11 +40623,22 @@ package android.telecom {
|
||||
method public void onRttStatusChanged(android.telecom.Call, boolean, android.telecom.Call.RttCall);
|
||||
method public void onStateChanged(android.telecom.Call, int);
|
||||
method public void onVideoCallChanged(android.telecom.Call, android.telecom.InCallService.VideoCall);
|
||||
field public static final int ANSWER_FAILED_ENDPOINT_REJECTED = 3; // 0x3
|
||||
field public static final int ANSWER_FAILED_ENDPOINT_TIMEOUT = 2; // 0x2
|
||||
field public static final int ANSWER_FAILED_ENDPOINT_UNAVAILABLE = 1; // 0x1
|
||||
field public static final int ANSWER_FAILED_UNKNOWN_REASON = 0; // 0x0
|
||||
field public static final int HANDOVER_FAILURE_DEST_APP_REJECTED = 1; // 0x1
|
||||
field public static final int HANDOVER_FAILURE_NOT_SUPPORTED = 2; // 0x2
|
||||
field public static final int HANDOVER_FAILURE_ONGOING_EMERGENCY_CALL = 4; // 0x4
|
||||
field public static final int HANDOVER_FAILURE_UNKNOWN = 5; // 0x5
|
||||
field public static final int HANDOVER_FAILURE_USER_REJECTED = 3; // 0x3
|
||||
field public static final int PULL_FAILED_ENDPOINT_REJECTED = 2; // 0x2
|
||||
field public static final int PULL_FAILED_ENDPOINT_TIMEOUT = 1; // 0x1
|
||||
field public static final int PULL_FAILED_UNKNOWN_REASON = 0; // 0x0
|
||||
field public static final int PUSH_FAILED_ENDPOINT_REJECTED = 3; // 0x3
|
||||
field public static final int PUSH_FAILED_ENDPOINT_TIMEOUT = 2; // 0x2
|
||||
field public static final int PUSH_FAILED_ENDPOINT_UNAVAILABLE = 1; // 0x1
|
||||
field public static final int PUSH_FAILED_UNKNOWN_REASON = 0; // 0x0
|
||||
}
|
||||
|
||||
public static class Call.Details {
|
||||
@@ -40629,6 +40646,8 @@ package android.telecom {
|
||||
method public boolean can(int);
|
||||
method public static String capabilitiesToString(int);
|
||||
method public android.telecom.PhoneAccountHandle getAccountHandle();
|
||||
method @Nullable public android.telecom.CallEndpoint getActiveCallEndpoint();
|
||||
method @NonNull public java.util.Set<android.telecom.CallEndpoint> getAvailableCallEndpoints();
|
||||
method public int getCallCapabilities();
|
||||
method public int getCallDirection();
|
||||
method public int getCallProperties();
|
||||
@@ -40722,6 +40741,34 @@ 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 android.os.ParcelUuid, @NonNull CharSequence, int, @NonNull android.content.ComponentName);
|
||||
method public int describeContents();
|
||||
method @NonNull public CharSequence getDescription();
|
||||
method @NonNull public android.os.ParcelUuid getIdentifier();
|
||||
method public int getType();
|
||||
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 ENDPOINT_TYPE_TETHERED = 2; // 0x2
|
||||
field public static final int ENDPOINT_TYPE_UNTETHERED = 1; // 0x1
|
||||
}
|
||||
|
||||
public interface CallEndpointCallback {
|
||||
method public void onCallEndpointSessionActivationTimeout();
|
||||
method public void onCallEndpointSessionDeactivated();
|
||||
}
|
||||
|
||||
public class CallEndpointSession {
|
||||
method public void setCallEndpointSessionActivated();
|
||||
method public void setCallEndpointSessionActivationFailed(int);
|
||||
method public void setCallEndpointSessionDeactivated();
|
||||
field public static final int ACTIVATION_FAILURE_REJECTED = 1; // 0x1
|
||||
field public static final int ACTIVATION_FAILURE_UNAVAILABLE = 0; // 0x0
|
||||
field public static final int ANSWER_REQUEST = 1; // 0x1
|
||||
field public static final int PLACE_REQUEST = 3; // 0x3
|
||||
field public static final int PUSH_REQUEST = 2; // 0x2
|
||||
}
|
||||
|
||||
public abstract class CallRedirectionService extends android.app.Service {
|
||||
ctor public CallRedirectionService();
|
||||
method public final void cancelCall();
|
||||
@@ -40991,7 +41038,6 @@ package android.telecom {
|
||||
field public static final int PROPERTY_IS_RTT = 256; // 0x100
|
||||
field public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 1024; // 0x400
|
||||
field public static final int PROPERTY_SELF_MANAGED = 128; // 0x80
|
||||
field public static final int PROPERTY_TETHERED_CALL = 16384; // 0x4000
|
||||
field public static final int PROPERTY_WIFI = 8; // 0x8
|
||||
field public static final int STATE_ACTIVE = 4; // 0x4
|
||||
field public static final int STATE_DIALING = 3; // 0x3
|
||||
@@ -41125,6 +41171,8 @@ package android.telecom {
|
||||
field public static final int OTHER = 9; // 0x9
|
||||
field public static final String REASON_EMERGENCY_CALL_PLACED = "REASON_EMERGENCY_CALL_PLACED";
|
||||
field public static final String REASON_EMULATING_SINGLE_CALL = "EMULATING_SINGLE_CALL";
|
||||
field public static final String REASON_ENDPOINT_REJECTED = "REASON_ENDPOINT_REJECTED";
|
||||
field public static final String REASON_ENDPOINT_SESSION_DEACTIVATED = "REASON_ENDPOINT_SESSION_DEACTIVATED";
|
||||
field public static final String REASON_IMS_ACCESS_BLOCKED = "REASON_IMS_ACCESS_BLOCKED";
|
||||
field public static final String REASON_WIFI_ON_BUT_WFC_OFF = "REASON_WIFI_ON_BUT_WFC_OFF";
|
||||
field public static final int REJECTED = 6; // 0x6
|
||||
@@ -41153,6 +41201,7 @@ package android.telecom {
|
||||
method public void onBringToForeground(boolean);
|
||||
method public void onCallAdded(android.telecom.Call);
|
||||
method public void onCallAudioStateChanged(android.telecom.CallAudioState);
|
||||
method @NonNull public android.telecom.CallEndpointCallback onCallEndpointActivationRequested(@NonNull android.telecom.CallEndpoint, @NonNull android.telecom.CallEndpointSession) throws java.lang.UnsupportedOperationException;
|
||||
method public void onCallRemoved(android.telecom.Call);
|
||||
method public void onCanAddCallChanged(boolean);
|
||||
method public void onConnectionEvent(android.telecom.Call, String, android.os.Bundle);
|
||||
@@ -41415,6 +41464,7 @@ package android.telecom {
|
||||
method @Deprecated @RequiresPermission(android.Manifest.permission.ANSWER_PHONE_CALLS) public boolean endCall();
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.net.Uri getAdnUriForPhoneAccount(android.telecom.PhoneAccountHandle);
|
||||
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<android.telecom.PhoneAccountHandle> getCallCapablePhoneAccounts();
|
||||
method @NonNull public java.util.Set<android.telecom.CallEndpoint> getCallEndpoints();
|
||||
method public String getDefaultDialerPackage();
|
||||
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public android.telecom.PhoneAccountHandle getDefaultOutgoingPhoneAccount(String);
|
||||
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.READ_SMS, android.Manifest.permission.READ_PHONE_NUMBERS}, conditional=true) public String getLine1Number(android.telecom.PhoneAccountHandle);
|
||||
@@ -41435,10 +41485,12 @@ package android.telecom {
|
||||
method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PHONE_STATE}) public boolean isTtySupported();
|
||||
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isVoiceMailNumber(android.telecom.PhoneAccountHandle, String);
|
||||
method @RequiresPermission(anyOf={android.Manifest.permission.CALL_PHONE, android.Manifest.permission.MANAGE_OWN_CALLS}) public void placeCall(android.net.Uri, android.os.Bundle);
|
||||
method public void registerCallEndpoints(@NonNull java.util.Set<android.telecom.CallEndpoint>);
|
||||
method public void registerPhoneAccount(android.telecom.PhoneAccount);
|
||||
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void showInCallScreen(boolean);
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void silenceRinger();
|
||||
method @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void startConference(@NonNull java.util.List<android.net.Uri>, @NonNull android.os.Bundle);
|
||||
method public void unregisterCallEndpoints(@NonNull java.util.Set<android.telecom.CallEndpoint>);
|
||||
method public void unregisterPhoneAccount(android.telecom.PhoneAccountHandle);
|
||||
field public static final String ACTION_CHANGE_DEFAULT_DIALER = "android.telecom.action.CHANGE_DEFAULT_DIALER";
|
||||
field public static final String ACTION_CHANGE_PHONE_ACCOUNTS = "android.telecom.action.CHANGE_PHONE_ACCOUNTS";
|
||||
@@ -41482,6 +41534,7 @@ package android.telecom {
|
||||
field public static final String EXTRA_PHONE_ACCOUNT_HANDLE = "android.telecom.extra.PHONE_ACCOUNT_HANDLE";
|
||||
field public static final String EXTRA_PICTURE_URI = "android.telecom.extra.PICTURE_URI";
|
||||
field public static final String EXTRA_PRIORITY = "android.telecom.extra.PRIORITY";
|
||||
field public static final String EXTRA_START_CALL_ON_ENDPOINT = "android.telecom.extra.START_CALL_ON_ENDPOINT";
|
||||
field public static final String EXTRA_START_CALL_WITH_RTT = "android.telecom.extra.START_CALL_WITH_RTT";
|
||||
field public static final String EXTRA_START_CALL_WITH_SPEAKERPHONE = "android.telecom.extra.START_CALL_WITH_SPEAKERPHONE";
|
||||
field public static final String EXTRA_START_CALL_WITH_VIDEO_STATE = "android.telecom.extra.START_CALL_WITH_VIDEO_STATE";
|
||||
@@ -41493,6 +41546,7 @@ package android.telecom {
|
||||
field public static final String METADATA_IN_CALL_SERVICE_CAR_MODE_UI = "android.telecom.IN_CALL_SERVICE_CAR_MODE_UI";
|
||||
field public static final String METADATA_IN_CALL_SERVICE_RINGING = "android.telecom.IN_CALL_SERVICE_RINGING";
|
||||
field public static final String METADATA_IN_CALL_SERVICE_UI = "android.telecom.IN_CALL_SERVICE_UI";
|
||||
field public static final String METADATA_STREAMING_TETHERED_CALLS = "android.telecom.STREAMING_TETHERED_CALLS";
|
||||
field public static final int PRESENTATION_ALLOWED = 1; // 0x1
|
||||
field public static final int PRESENTATION_PAYPHONE = 4; // 0x4
|
||||
field public static final int PRESENTATION_RESTRICTED = 2; // 0x2
|
||||
|
||||
@@ -43,6 +43,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
@@ -571,7 +572,7 @@ public final class Call {
|
||||
public static final int CAPABILITY_REMOTE_PARTY_SUPPORTS_RTT = 0x10000000;
|
||||
|
||||
//******************************************************************************************
|
||||
// Next CAPABILITY value: 0x20000000
|
||||
// Next CAPABILITY value: 0x40000000
|
||||
//******************************************************************************************
|
||||
|
||||
/**
|
||||
@@ -733,6 +734,8 @@ public final class Call {
|
||||
private final String mContactDisplayName;
|
||||
private final @CallDirection int mCallDirection;
|
||||
private final @Connection.VerificationStatus int mCallerNumberVerificationStatus;
|
||||
private final CallEndpoint mActiveCallEndpoint;
|
||||
private final Set<CallEndpoint> mAvailableCallEndpoint;
|
||||
|
||||
/**
|
||||
* Whether the supplied capabilities supports the specified capability.
|
||||
@@ -1116,32 +1119,52 @@ public final class Call {
|
||||
return mCallerNumberVerificationStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return set of available {@link CallEndpoint} which can be used to push or answer this
|
||||
* call via {@link #pushCall(CallEndpoint)} or {@link #answerCall(CallEndpoint, int)}.
|
||||
* @return Set of available call endpoints.
|
||||
*/
|
||||
public @NonNull Set<CallEndpoint> getAvailableCallEndpoints() {
|
||||
return mAvailableCallEndpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link CallEndpoint} which is currently active for a call. If the call does
|
||||
* not take place via any {@link CallEndpoint}, return {@code null}.
|
||||
* @return Current active endpoint.
|
||||
*/
|
||||
public @Nullable CallEndpoint getActiveCallEndpoint() {
|
||||
return mActiveCallEndpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Details) {
|
||||
Details d = (Details) o;
|
||||
return
|
||||
Objects.equals(mState, d.mState) &&
|
||||
Objects.equals(mHandle, d.mHandle) &&
|
||||
Objects.equals(mHandlePresentation, d.mHandlePresentation) &&
|
||||
Objects.equals(mCallerDisplayName, d.mCallerDisplayName) &&
|
||||
Objects.equals(mCallerDisplayNamePresentation,
|
||||
d.mCallerDisplayNamePresentation) &&
|
||||
Objects.equals(mAccountHandle, d.mAccountHandle) &&
|
||||
Objects.equals(mCallCapabilities, d.mCallCapabilities) &&
|
||||
Objects.equals(mCallProperties, d.mCallProperties) &&
|
||||
Objects.equals(mDisconnectCause, d.mDisconnectCause) &&
|
||||
Objects.equals(mConnectTimeMillis, d.mConnectTimeMillis) &&
|
||||
Objects.equals(mGatewayInfo, d.mGatewayInfo) &&
|
||||
Objects.equals(mVideoState, d.mVideoState) &&
|
||||
Objects.equals(mStatusHints, d.mStatusHints) &&
|
||||
areBundlesEqual(mExtras, d.mExtras) &&
|
||||
areBundlesEqual(mIntentExtras, d.mIntentExtras) &&
|
||||
Objects.equals(mCreationTimeMillis, d.mCreationTimeMillis) &&
|
||||
Objects.equals(mContactDisplayName, d.mContactDisplayName) &&
|
||||
Objects.equals(mCallDirection, d.mCallDirection) &&
|
||||
Objects.equals(mCallerNumberVerificationStatus,
|
||||
d.mCallerNumberVerificationStatus);
|
||||
Objects.equals(mState, d.mState)
|
||||
&& Objects.equals(mHandle, d.mHandle)
|
||||
&& Objects.equals(mHandlePresentation, d.mHandlePresentation)
|
||||
&& Objects.equals(mCallerDisplayName, d.mCallerDisplayName)
|
||||
&& Objects.equals(mCallerDisplayNamePresentation,
|
||||
d.mCallerDisplayNamePresentation)
|
||||
&& Objects.equals(mAccountHandle, d.mAccountHandle)
|
||||
&& Objects.equals(mCallCapabilities, d.mCallCapabilities)
|
||||
&& Objects.equals(mCallProperties, d.mCallProperties)
|
||||
&& Objects.equals(mDisconnectCause, d.mDisconnectCause)
|
||||
&& Objects.equals(mConnectTimeMillis, d.mConnectTimeMillis)
|
||||
&& Objects.equals(mGatewayInfo, d.mGatewayInfo)
|
||||
&& Objects.equals(mVideoState, d.mVideoState)
|
||||
&& Objects.equals(mStatusHints, d.mStatusHints)
|
||||
&& areBundlesEqual(mExtras, d.mExtras)
|
||||
&& areBundlesEqual(mIntentExtras, d.mIntentExtras)
|
||||
&& Objects.equals(mCreationTimeMillis, d.mCreationTimeMillis)
|
||||
&& Objects.equals(mContactDisplayName, d.mContactDisplayName)
|
||||
&& Objects.equals(mCallDirection, d.mCallDirection)
|
||||
&& Objects.equals(mCallerNumberVerificationStatus,
|
||||
d.mCallerNumberVerificationStatus)
|
||||
&& Objects.equals(mActiveCallEndpoint, d.mActiveCallEndpoint)
|
||||
&& Objects.equals(mAvailableCallEndpoint, d.mAvailableCallEndpoint);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1190,7 +1213,9 @@ public final class Call {
|
||||
long creationTimeMillis,
|
||||
String contactDisplayName,
|
||||
int callDirection,
|
||||
int callerNumberVerificationStatus) {
|
||||
int callerNumberVerificationStatus,
|
||||
CallEndpoint activeCallEndpoint,
|
||||
Set<CallEndpoint> availableCallEndpoints) {
|
||||
mState = state;
|
||||
mTelecomCallId = telecomCallId;
|
||||
mHandle = handle;
|
||||
@@ -1211,6 +1236,8 @@ public final class Call {
|
||||
mContactDisplayName = contactDisplayName;
|
||||
mCallDirection = callDirection;
|
||||
mCallerNumberVerificationStatus = callerNumberVerificationStatus;
|
||||
mActiveCallEndpoint = activeCallEndpoint;
|
||||
mAvailableCallEndpoint = availableCallEndpoints;
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
@@ -1235,7 +1262,9 @@ public final class Call {
|
||||
parcelableCall.getCreationTimeMillis(),
|
||||
parcelableCall.getContactDisplayName(),
|
||||
parcelableCall.getCallDirection(),
|
||||
parcelableCall.getCallerNumberVerificationStatus());
|
||||
parcelableCall.getCallerNumberVerificationStatus(),
|
||||
parcelableCall.getActiveCallEndpoint(),
|
||||
parcelableCall.getAvailableCallEndpoints());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1257,6 +1286,10 @@ public final class Call {
|
||||
sb.append(capabilitiesToString(mCallCapabilities));
|
||||
sb.append(", props: ");
|
||||
sb.append(propertiesToString(mCallProperties));
|
||||
sb.append(", activeEndpoint: ");
|
||||
sb.append(mActiveCallEndpoint);
|
||||
sb.append(", availableEndpoints: ");
|
||||
sb.append(mAvailableCallEndpoint);
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
@@ -1355,6 +1388,121 @@ public final class Call {
|
||||
*/
|
||||
public static final int HANDOVER_FAILURE_UNKNOWN = 5;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@IntDef(prefix = { "PUSH_FAILED_" },
|
||||
value = {PUSH_FAILED_UNKNOWN_REASON, PUSH_FAILED_ENDPOINT_UNAVAILABLE,
|
||||
PUSH_FAILED_ENDPOINT_TIMEOUT, PUSH_FAILED_ENDPOINT_REJECTED})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface PushFailedReason {}
|
||||
|
||||
/**
|
||||
* Answer failure reason returned via {@link #onAnswerFailed(CallEndpoint, int)} when a push
|
||||
* fails due to unknown reason.
|
||||
* <p>
|
||||
* For more information on push call, see {@link #pushCall(CallEndpoint)}.
|
||||
*/
|
||||
public static final int PUSH_FAILED_UNKNOWN_REASON = 0;
|
||||
|
||||
/**
|
||||
* Push failure reason returned via {@link #onCallPushFailed(CallEndpoint, int)} when a push
|
||||
* fails due to requested endpoint is unavailable.
|
||||
* <p>
|
||||
* For more information on push call, see {@link #pushCall(CallEndpoint)}.
|
||||
*/
|
||||
public static final int PUSH_FAILED_ENDPOINT_UNAVAILABLE = 1;
|
||||
|
||||
/**
|
||||
* Push failure reason returned via {@link #onCallPushFailed(CallEndpoint, int)} when a push
|
||||
* fails due to requested endpoint takes too long to handle the request.
|
||||
* <p>
|
||||
* For more information on push call, see {@link #pushCall(CallEndpoint)}.
|
||||
*/
|
||||
public static final int PUSH_FAILED_ENDPOINT_TIMEOUT = 2;
|
||||
|
||||
/**
|
||||
* Push failure reason returned via {@link #onCallPushFailed(CallEndpoint, int)} when a push
|
||||
* fails due to endpoint rejected the request.
|
||||
* <p>
|
||||
* For more information on push call, see {@link #pushCall(CallEndpoint)}.
|
||||
*/
|
||||
public static final int PUSH_FAILED_ENDPOINT_REJECTED = 3;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@IntDef(prefix = { "ANSWER_FAILED_" },
|
||||
value = {ANSWER_FAILED_UNKNOWN_REASON, ANSWER_FAILED_ENDPOINT_UNAVAILABLE,
|
||||
ANSWER_FAILED_ENDPOINT_TIMEOUT, ANSWER_FAILED_ENDPOINT_REJECTED})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface AnswerFailedReason {}
|
||||
|
||||
/**
|
||||
* Answer failure reason returned via {@link #onAnswerFailed(CallEndpoint, int)} when it
|
||||
* fails due to unknown reason.
|
||||
* <p>
|
||||
* For more information on answer call, see {@link #answerCall(CallEndpoint, int)}.
|
||||
*/
|
||||
public static final int ANSWER_FAILED_UNKNOWN_REASON = 0;
|
||||
|
||||
/**
|
||||
* Answer failure reason returned via {@link #onAnswerFailed(CallEndpoint, int)} when it
|
||||
* fails due to requested endpoint is unavailable.
|
||||
* <p>
|
||||
* For more information on answer call, see {@link #answerCall(CallEndpoint, int)}.
|
||||
*/
|
||||
public static final int ANSWER_FAILED_ENDPOINT_UNAVAILABLE = 1;
|
||||
|
||||
/**
|
||||
* Answer failure reason returned via {@link #onAnswerFailed(CallEndpoint, int)} when it
|
||||
* fails due to requested endpoint takes too long to handle the request.
|
||||
* <p>
|
||||
* For more information on answer call, see {@link #answerCall(CallEndpoint, int)}.
|
||||
*/
|
||||
public static final int ANSWER_FAILED_ENDPOINT_TIMEOUT = 2;
|
||||
|
||||
/**
|
||||
* Answer failure reason returned via {@link #onAnswerFailed(CallEndpoint, int)} when it
|
||||
* fails due to endpoint rejected the request.
|
||||
* <p>
|
||||
* For more information on answer call, see {@link #answerCall(CallEndpoint, int)}.
|
||||
*/
|
||||
public static final int ANSWER_FAILED_ENDPOINT_REJECTED = 3;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@IntDef(prefix = { "PULL_FAILED_" },
|
||||
value = {PULL_FAILED_UNKNOWN_REASON, PULL_FAILED_ENDPOINT_TIMEOUT,
|
||||
PULL_FAILED_ENDPOINT_REJECTED})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface PullFailedReason {}
|
||||
|
||||
/**
|
||||
* Pull failure reason returned via {@link #onCallPullFailed(int)} when it fails due to
|
||||
* unknown reason.
|
||||
* <p>
|
||||
* For more information on pull call, see {@link #pullCall()}.
|
||||
*/
|
||||
public static final int PULL_FAILED_UNKNOWN_REASON = 0;
|
||||
|
||||
/**
|
||||
* Pull failure reason returned via {@link #onCallPullFailed(int)} when it fails due to
|
||||
* requested endpoint takes too long to handle the request.
|
||||
* <p>
|
||||
* For more information on pull call, see {@link #pullCall()}.
|
||||
*/
|
||||
public static final int PULL_FAILED_ENDPOINT_TIMEOUT = 1;
|
||||
|
||||
/**
|
||||
* Pull failure reason returned via {@link #onCallPullFailed(int)} when it fails due to
|
||||
* endpoint rejected the request.
|
||||
* <p>
|
||||
* For more information on pull call, see {@link #pullCall()}.
|
||||
*/
|
||||
public static final int PULL_FAILED_ENDPOINT_REJECTED = 2;
|
||||
|
||||
/**
|
||||
* Invoked when the state of this {@code Call} has changed. See {@link #getState()}.
|
||||
*
|
||||
@@ -1515,6 +1663,31 @@ public final class Call {
|
||||
* @param failureReason Error reason for failure.
|
||||
*/
|
||||
public void onHandoverFailed(Call call, @HandoverFailureErrors int failureReason) {}
|
||||
|
||||
/**
|
||||
* Invoked when call push request via {@link #pushCall(CallEndpoint)} has failed.
|
||||
*
|
||||
* @param endpoint The endpoint requested to push the call to.
|
||||
* @param reason Failed reason.
|
||||
*/
|
||||
public void onCallPushFailed(@NonNull CallEndpoint endpoint, @PushFailedReason int reason)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Invoked when answer call request via {@link #answerCall(CallEndpoint, int)} has failed.
|
||||
*
|
||||
* @param endpoint The endpoint requested to answer the call.
|
||||
* @param reason Failed reason
|
||||
*/
|
||||
public void onAnswerFailed(@NonNull CallEndpoint endpoint, @AnswerFailedReason int reason)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Invoked when pull call request via {@link #pullCall()} has failed.
|
||||
*
|
||||
* @param reason Failed reason
|
||||
*/
|
||||
public void onCallPullFailed(@PullFailedReason int reason) {}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1935,9 +2108,22 @@ public final class Call {
|
||||
mInCallAdapter.addConferenceParticipants(mTelecomCallId, participants);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #pullCall()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void pullExternalCall() {
|
||||
// If this isn't an external call, ignore the request.
|
||||
if (!mDetails.hasProperty(Details.PROPERTY_IS_EXTERNAL_CALL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mInCallAdapter.pullExternalCall(mTelecomCallId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiates a request to the {@link ConnectionService} to pull an external call to the local
|
||||
* device.
|
||||
* device, or to bring a tethered call back to the local device.
|
||||
* <p>
|
||||
* Calls to this method are ignored if the call does not have the
|
||||
* {@link Call.Details#PROPERTY_IS_EXTERNAL_CALL} property set.
|
||||
@@ -1946,13 +2132,34 @@ public final class Call {
|
||||
* {@link TelecomManager#METADATA_INCLUDE_EXTERNAL_CALLS} metadata set to {@code true}
|
||||
* in its manifest.
|
||||
*/
|
||||
public void pullExternalCall() {
|
||||
// If this isn't an external call, ignore the request.
|
||||
if (!mDetails.hasProperty(Details.PROPERTY_IS_EXTERNAL_CALL)) {
|
||||
return;
|
||||
}
|
||||
public void pullCall() {
|
||||
pullExternalCall();
|
||||
}
|
||||
|
||||
mInCallAdapter.pullExternalCall(mTelecomCallId);
|
||||
/**
|
||||
* Initiates a request to the {@link ConnectionService} to push a call to a
|
||||
* {@link CallEndpoint}.
|
||||
* <p>
|
||||
*
|
||||
* @param endpoint The call endpoint to which the call will be pushed.
|
||||
*/
|
||||
public void pushCall(@NonNull CallEndpoint endpoint) {
|
||||
mInCallAdapter.pushCall(mTelecomCallId, endpoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiates a request to the {@link ConnectionService} to answer a call to a
|
||||
* {@link CallEndpoint}.
|
||||
* <p>
|
||||
* Calls to this method are ignored if the call does not have the
|
||||
* {@link Call.Details#CAPABILITY_CAN_PULL_CALL} capability set.
|
||||
*
|
||||
* @param endpoint The call endpoint on which to answer the call.
|
||||
* @param videoState The video state in which to answer the call.
|
||||
*/
|
||||
public void answerCall(@NonNull CallEndpoint endpoint,
|
||||
@VideoProfile.VideoState int videoState) {
|
||||
mInCallAdapter.answerCall(mTelecomCallId, endpoint, videoState);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2633,7 +2840,9 @@ public final class Call {
|
||||
mDetails.getCreationTimeMillis(),
|
||||
mDetails.getContactDisplayName(),
|
||||
mDetails.getCallDirection(),
|
||||
mDetails.getCallerNumberVerificationStatus()
|
||||
mDetails.getCallerNumberVerificationStatus(),
|
||||
mDetails.getActiveCallEndpoint(),
|
||||
mDetails.getAvailableCallEndpoints()
|
||||
);
|
||||
fireDetailsChanged(mDetails);
|
||||
}
|
||||
@@ -2675,7 +2884,7 @@ public final class Call {
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
final void internalOnHandoverComplete() {
|
||||
void internalOnHandoverComplete() {
|
||||
for (CallbackRecord<Callback> record : mCallbackRecords) {
|
||||
final Call call = this;
|
||||
final Callback callback = record.getCallback();
|
||||
@@ -2683,6 +2892,32 @@ public final class Call {
|
||||
}
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
void internalOnCallPullFailed(@Callback.PullFailedReason int reason) {
|
||||
for (CallbackRecord<Callback> record : mCallbackRecords) {
|
||||
final Callback callback = record.getCallback();
|
||||
record.getHandler().post(() -> callback.onCallPullFailed(reason));
|
||||
}
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
void internalOnCallPushFailed(CallEndpoint callEndpoint,
|
||||
@Callback.PushFailedReason int reason) {
|
||||
for (CallbackRecord<Callback> record : mCallbackRecords) {
|
||||
final Callback callback = record.getCallback();
|
||||
record.getHandler().post(() -> callback.onCallPushFailed(callEndpoint, reason));
|
||||
}
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
void internalOnAnswerFailed(CallEndpoint callEndpoint,
|
||||
@Callback.AnswerFailedReason int reason) {
|
||||
for (CallbackRecord<Callback> record : mCallbackRecords) {
|
||||
final Callback callback = record.getCallback();
|
||||
record.getHandler().post(() -> callback.onAnswerFailed(callEndpoint, reason));
|
||||
}
|
||||
}
|
||||
|
||||
private void fireStateChanged(final int newState) {
|
||||
for (CallbackRecord<Callback> record : mCallbackRecords) {
|
||||
final Call call = this;
|
||||
|
||||
22
telecomm/java/android/telecom/CallEndpoint.aidl
Normal file
22
telecomm/java/android/telecom/CallEndpoint.aidl
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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;
|
||||
150
telecomm/java/android/telecom/CallEndpoint.java
Normal file
150
telecomm/java/android/telecom/CallEndpoint.java
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.content.ComponentName;
|
||||
import android.os.Parcel;
|
||||
import android.os.ParcelUuid;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents the endpoint on which a call can be carried by the user.
|
||||
*
|
||||
* For example, the user may be able to carry out a call on another device on their local network
|
||||
* using a call streaming solution, or may be able to carry out a call on another device registered
|
||||
* with the same mobile line of service.
|
||||
*/
|
||||
public final class CallEndpoint implements Parcelable {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@IntDef(prefix = {"ENDPOINT_TYPE_"},
|
||||
value = {ENDPOINT_TYPE_TETHERED, ENDPOINT_TYPE_UNTETHERED})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface EndpointType {}
|
||||
|
||||
/** Indicates the endpoint contains a complete calling stack and is capable of carrying out a
|
||||
* call on its own. Untethered endpoints are typically other devices which share the same
|
||||
* mobile line of service as the current device.
|
||||
*/
|
||||
public static final int ENDPOINT_TYPE_UNTETHERED = 1;
|
||||
|
||||
/** Indicates the endpoint itself doesn't have the required calling infrastructure in order to
|
||||
* complete a call on its own. Tethered endpoints depend on a call streaming solution to
|
||||
* transport the media and control for a call to another device, while depending on the current
|
||||
* device to connect the call to the mobile network.
|
||||
*/
|
||||
public static final int ENDPOINT_TYPE_TETHERED = 2;
|
||||
|
||||
private final ParcelUuid mUuid;
|
||||
private CharSequence mDescription;
|
||||
private final int mType;
|
||||
private final ComponentName mComponentName;
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
mUuid.writeToParcel(dest, flags);
|
||||
dest.writeCharSequence(mDescription);
|
||||
dest.writeInt(mType);
|
||||
mComponentName.writeToParcel(dest, flags);
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Creator<CallEndpoint> CREATOR =
|
||||
new Creator<CallEndpoint>() {
|
||||
@Override
|
||||
public CallEndpoint createFromParcel(Parcel in) {
|
||||
return new CallEndpoint(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallEndpoint[] newArray(int size) {
|
||||
return new CallEndpoint[size];
|
||||
}
|
||||
};
|
||||
|
||||
public CallEndpoint(@NonNull ParcelUuid uuid, @NonNull CharSequence description, int type,
|
||||
@NonNull ComponentName componentName) {
|
||||
mUuid = uuid;
|
||||
mDescription = description;
|
||||
mType = type;
|
||||
mComponentName = componentName;
|
||||
}
|
||||
|
||||
private CallEndpoint(@NonNull Parcel in) {
|
||||
this(ParcelUuid.CREATOR.createFromParcel(in), in.readCharSequence(), in.readInt(),
|
||||
ComponentName.CREATOR.createFromParcel(in));
|
||||
}
|
||||
|
||||
/**
|
||||
* A unique identifier for this call endpoint. An endpoint provider should take care to use an
|
||||
* identifier which is stable for the current association between an endpoint and the current
|
||||
* device, but which is not globally identifying.
|
||||
* @return the unique identifier.
|
||||
*/
|
||||
public @NonNull ParcelUuid getIdentifier() {
|
||||
return mUuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* A human-readable description of this {@link CallEndpoint}. An {@link InCallService} uses
|
||||
* when informing the user of the endpoint.
|
||||
* @return the description.
|
||||
*/
|
||||
public @NonNull CharSequence getDescription() {
|
||||
return mDescription;
|
||||
}
|
||||
|
||||
public @EndpointType int getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public @NonNull ComponentName getComponentName() {
|
||||
return mComponentName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof CallEndpoint) {
|
||||
CallEndpoint d = (CallEndpoint) o;
|
||||
return Objects.equals(mUuid, d.mUuid)
|
||||
&& Objects.equals(mDescription, d.mDescription)
|
||||
&& Objects.equals(mType, d.mType)
|
||||
&& Objects.equals(mComponentName, d.mComponentName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mUuid, mDescription, mType, mComponentName);
|
||||
}
|
||||
}
|
||||
38
telecomm/java/android/telecom/CallEndpointCallback.java
Normal file
38
telecomm/java/android/telecom/CallEndpointCallback.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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;
|
||||
|
||||
/**
|
||||
* Provides callbacks from telecom to the cross device call streaming app with lifecycle events
|
||||
* related to an {@link CallEndpointSession}.
|
||||
*/
|
||||
public interface CallEndpointCallback {
|
||||
/**
|
||||
* Invoked by telecom when a {@link CallEndpointSession} is started but the streaming app has
|
||||
* not activated the endpoint in a timely manner and the framework deems the activation request
|
||||
* to have timed out.
|
||||
*/
|
||||
void onCallEndpointSessionActivationTimeout();
|
||||
|
||||
/**
|
||||
* Invoked by telecom when {@link CallEndpointSession#setCallEndpointSessionDeactivated()}
|
||||
* called by a cross device call streaming app, or when the app uninstalled. When a tethered
|
||||
* {@link CallEndpoint} is deactivated, the call streaming app should clean up any
|
||||
* audio/network resources and stop relaying call controls from the endpoint.
|
||||
*/
|
||||
void onCallEndpointSessionDeactivated();
|
||||
}
|
||||
122
telecomm/java/android/telecom/CallEndpointSession.java
Normal file
122
telecomm/java/android/telecom/CallEndpointSession.java
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import com.android.internal.telecom.ICallEndpointSession;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
|
||||
/**
|
||||
* Provides method and necessary information for cross device call streaming app to streams calls
|
||||
* and updates to the status of the endpoint.
|
||||
*
|
||||
*/
|
||||
public class CallEndpointSession {
|
||||
/**
|
||||
* Indicates that this call endpoint session is activated by
|
||||
* {@link Call#answerCall(CallEndpoint, int)} from the original device.
|
||||
*/
|
||||
public static final int ANSWER_REQUEST = 1;
|
||||
|
||||
/**
|
||||
* Indicates that this call endpoint session is activated by {@link Call#pushCall(CallEndpoint)}
|
||||
* from the original device.
|
||||
*/
|
||||
public static final int PUSH_REQUEST = 2;
|
||||
|
||||
/**
|
||||
* Indicates that this call endpoint session is activated by
|
||||
* {@link TelecomManager#placeCall(Uri, Bundle)} with extra
|
||||
* {@link TelecomManager#EXTRA_START_CALL_ON_ENDPOINT} set.
|
||||
*/
|
||||
public static final int PLACE_REQUEST = 3;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@IntDef(prefix = {"ACTIVATION_FAILURE_"},
|
||||
value = {ACTIVATION_FAILURE_REJECTED, ACTIVATION_FAILURE_UNAVAILABLE})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface ActivationFailureReason {}
|
||||
/**
|
||||
* Used as reason for {@link #setCallEndpointSessionActivationFailed(int)} to inform the
|
||||
* endpoint is no longer present on the network.
|
||||
*/
|
||||
public static final int ACTIVATION_FAILURE_UNAVAILABLE = 0;
|
||||
|
||||
/**
|
||||
* Used as reason for {@link #setCallEndpointSessionActivationFailed(int)} to inform the
|
||||
* remote endpoint rejected the request to start streaming a cross device call.
|
||||
*/
|
||||
public static final int ACTIVATION_FAILURE_REJECTED = 1;
|
||||
|
||||
private final ICallEndpointSession mCallEndpointSession;
|
||||
|
||||
/**
|
||||
* {@hide}
|
||||
*/
|
||||
public CallEndpointSession(ICallEndpointSession callEndpointSession) {
|
||||
mCallEndpointSession = callEndpointSession;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked by cross device call streaming app to inform telecom stack that the call endpoint is
|
||||
* now activated and that the call is being streamed to the endpoint.
|
||||
*/
|
||||
public void setCallEndpointSessionActivated() {
|
||||
try {
|
||||
mCallEndpointSession.setCallEndpointSessionActivated();
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked by cross device call streaming app to inform telecom stack that the call endpoint
|
||||
* could not be activated due to error.
|
||||
* Possible errors are:
|
||||
* <ul>
|
||||
* <li>{@link #ACTIVATION_FAILURE_UNAVAILABLE}</li>
|
||||
* <li>{@link #ACTIVATION_FAILURE_REJECTED}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param reason The reason for activation failure
|
||||
*/
|
||||
public void setCallEndpointSessionActivationFailed(@ActivationFailureReason int reason) {
|
||||
try {
|
||||
mCallEndpointSession.setCallEndpointSessionActivationFailed(reason);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked by cross device call streaming app to inform telecom stack that the call endpoint is
|
||||
* no longer active.
|
||||
*/
|
||||
public void setCallEndpointSessionDeactivated() {
|
||||
try {
|
||||
mCallEndpointSession.setCallEndpointSessionDeactivated();
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -561,15 +561,6 @@ public abstract class Connection extends Conferenceable {
|
||||
*/
|
||||
public static final int PROPERTY_CROSS_SIM = 1 << 13;
|
||||
|
||||
/**
|
||||
* Connection is a tethered external call.
|
||||
* <p>
|
||||
* Indicates that the {@link Connection} is fixed on this device but the audio streams are
|
||||
* re-routed to another device.
|
||||
* <p>
|
||||
*/
|
||||
public static final int PROPERTY_TETHERED_CALL = 1 << 14;
|
||||
|
||||
//**********************************************************************************************
|
||||
// Next PROPERTY value: 1<<14
|
||||
//**********************************************************************************************
|
||||
|
||||
@@ -111,6 +111,22 @@ public final class DisconnectCause implements Parcelable {
|
||||
*/
|
||||
public static final String REASON_EMERGENCY_CALL_PLACED = "REASON_EMERGENCY_CALL_PLACED";
|
||||
|
||||
/**
|
||||
* This reason is set when an call is ended due to {@link CallEndpoint} rejection.
|
||||
* This reason string should only be associated with the {@link #LOCAL} disconnect code returned
|
||||
* from {@link #getCode()}.
|
||||
*/
|
||||
public static final String REASON_ENDPOINT_REJECTED = "REASON_ENDPOINT_REJECTED";
|
||||
|
||||
/**
|
||||
* This reason is set when a call is ended due to {@link CallEndpoint} deactivated by
|
||||
* call disconnection or user terminated streaming.
|
||||
* This reason string should only be associated with the {@link #LOCAL} disconnect code returned
|
||||
* from {@link #getCode()}
|
||||
*/
|
||||
public static final String REASON_ENDPOINT_SESSION_DEACTIVATED =
|
||||
"REASON_ENDPOINT_SESSION_DEACTIVATED";
|
||||
|
||||
private int mDisconnectCode;
|
||||
private CharSequence mDisconnectLabel;
|
||||
private CharSequence mDisconnectDescription;
|
||||
|
||||
@@ -372,6 +372,34 @@ public final class InCallAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs Telecom to push a call to the given endpoint.
|
||||
*
|
||||
* @param callId The callId to push.
|
||||
* @param callEndpoint The endpoint to which the call will be pushed.
|
||||
*/
|
||||
public void pushCall(String callId, CallEndpoint callEndpoint) {
|
||||
try {
|
||||
mAdapter.pushCall(callId, callEndpoint);
|
||||
} catch (RemoteException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs Telecom to answer a call via the given endpoint.
|
||||
*
|
||||
* @param callId The callId to push.
|
||||
* @param callEndpoint The endpoint on which the call will be answered.
|
||||
* @param videoState The video state in which to answer the call.
|
||||
*/
|
||||
public void answerCall(String callId, CallEndpoint callEndpoint,
|
||||
@VideoProfile.VideoState int videoState) {
|
||||
try {
|
||||
mAdapter.answerCallViaEndpoint(callId, callEndpoint, videoState);
|
||||
} catch (RemoteException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Intructs Telecom to send a call event.
|
||||
*
|
||||
|
||||
@@ -30,9 +30,12 @@ import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.view.Surface;
|
||||
|
||||
import com.android.internal.os.SomeArgs;
|
||||
import com.android.internal.telecom.ICallEndpointCallback;
|
||||
import com.android.internal.telecom.ICallEndpointSession;
|
||||
import com.android.internal.telecom.IInCallAdapter;
|
||||
import com.android.internal.telecom.IInCallService;
|
||||
|
||||
@@ -258,6 +261,10 @@ public abstract class InCallService extends Service {
|
||||
private static final int MSG_ON_RTT_INITIATION_FAILURE = 11;
|
||||
private static final int MSG_ON_HANDOVER_FAILED = 12;
|
||||
private static final int MSG_ON_HANDOVER_COMPLETE = 13;
|
||||
private static final int MSG_ON_PUSH_FAILED = 14;
|
||||
private static final int MSG_ON_PULL_FAILED = 15;
|
||||
private static final int MSG_ON_ANSWER_EXTERNAL_FAILED = 16;
|
||||
private static final int MSG_ON_CALL_ENDPOINT_ACTIVATION_REQUEST = 17;
|
||||
|
||||
/** Default Handler used to consolidate binder method calls onto a single thread. */
|
||||
private final Handler mHandler = new Handler(Looper.getMainLooper()) {
|
||||
@@ -339,6 +346,66 @@ public abstract class InCallService extends Service {
|
||||
mPhone.internalOnHandoverComplete(callId);
|
||||
break;
|
||||
}
|
||||
case MSG_ON_PUSH_FAILED: {
|
||||
SomeArgs args = (SomeArgs) msg.obj;
|
||||
try {
|
||||
String callId = (String) args.arg1;
|
||||
CallEndpoint callEndpoint = (CallEndpoint) args.arg2;
|
||||
int reason = (int) args.arg3;
|
||||
mPhone.internalOnCallPushFailed(callId, callEndpoint, reason);
|
||||
} finally {
|
||||
args.recycle();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MSG_ON_PULL_FAILED: {
|
||||
SomeArgs args = (SomeArgs) msg.obj;
|
||||
try {
|
||||
String callId = (String) args.arg1;
|
||||
int reason = (int) args.arg2;
|
||||
mPhone.internalOnCallPullFailed(callId, reason);
|
||||
} finally {
|
||||
args.recycle();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MSG_ON_ANSWER_EXTERNAL_FAILED: {
|
||||
SomeArgs args = (SomeArgs) msg.obj;
|
||||
try {
|
||||
String callId = (String) args.arg1;
|
||||
CallEndpoint callEndpoint = (CallEndpoint) args.arg2;
|
||||
int reason = (int) args.arg3;
|
||||
mPhone.internalOnAnswerFailed(callId, callEndpoint, reason);
|
||||
} finally {
|
||||
args.recycle();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MSG_ON_CALL_ENDPOINT_ACTIVATION_REQUEST: {
|
||||
SomeArgs args = (SomeArgs) msg.obj;
|
||||
try {
|
||||
CallEndpoint callEndpoint = (CallEndpoint) args.arg1;
|
||||
ICallEndpointSession iCallEndpointSession =
|
||||
(ICallEndpointSession) args.arg2;
|
||||
try {
|
||||
mCallEndpointCallback = onCallEndpointActivationRequested(callEndpoint,
|
||||
new CallEndpointSession(iCallEndpointSession));
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// This InCallService neglected to implement
|
||||
// onCallEndpointActivationRequested, immediately signal back to Telecom
|
||||
// that the activation failed.
|
||||
try {
|
||||
iCallEndpointSession.setCallEndpointSessionActivationFailed(
|
||||
CallEndpointSession.ACTIVATION_FAILURE_UNAVAILABLE);
|
||||
} catch (RemoteException re) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
args.recycle();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -352,6 +419,36 @@ public abstract class InCallService extends Service {
|
||||
mHandler.obtainMessage(MSG_SET_IN_CALL_ADAPTER, inCallAdapter).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICallEndpointCallback requestCallEndpointActivation(CallEndpoint callEndpoint,
|
||||
ICallEndpointSession callEndpointSession) {
|
||||
SomeArgs args = SomeArgs.obtain();
|
||||
args.arg1 = callEndpoint;
|
||||
args.arg2 = callEndpointSession;
|
||||
mHandler.obtainMessage(MSG_ON_CALL_ENDPOINT_ACTIVATION_REQUEST, args).sendToTarget();
|
||||
|
||||
return new ICallEndpointCallback.Stub() {
|
||||
@Override
|
||||
public void onCallEndpointSessionActivationTimeout() throws RemoteException {
|
||||
if (mCallEndpointCallback != null) {
|
||||
mCallEndpointCallback.onCallEndpointSessionActivationTimeout();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCallEndpointSessionDeactivated() throws RemoteException {
|
||||
if (mCallEndpointCallback != null) {
|
||||
mCallEndpointCallback.onCallEndpointSessionDeactivated();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder asBinder() {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCall(ParcelableCall call) {
|
||||
mHandler.obtainMessage(MSG_ADD_CALL, call).sendToTarget();
|
||||
@@ -424,6 +521,32 @@ public abstract class InCallService extends Service {
|
||||
public void onHandoverComplete(String callId) {
|
||||
mHandler.obtainMessage(MSG_ON_HANDOVER_COMPLETE, callId).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCallPullFailed(String callId, int reason) {
|
||||
SomeArgs args = SomeArgs.obtain();
|
||||
args.arg1 = callId;
|
||||
args.arg2 = reason;
|
||||
mHandler.obtainMessage(MSG_ON_PULL_FAILED, args).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCallPushFailed(String callId, CallEndpoint endpoint, int reason) {
|
||||
SomeArgs args = SomeArgs.obtain();
|
||||
args.arg1 = callId;
|
||||
args.arg2 = endpoint;
|
||||
args.arg3 = reason;
|
||||
mHandler.obtainMessage(MSG_ON_PUSH_FAILED, args).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnswerFailed(String callId, CallEndpoint endpoint, int reason) {
|
||||
SomeArgs args = SomeArgs.obtain();
|
||||
args.arg1 = callId;
|
||||
args.arg2 = endpoint;
|
||||
args.arg3 = reason;
|
||||
mHandler.obtainMessage(MSG_ON_ANSWER_EXTERNAL_FAILED, args).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
private Phone.Listener mPhoneListener = new Phone.Listener() {
|
||||
@@ -470,6 +593,8 @@ public abstract class InCallService extends Service {
|
||||
};
|
||||
|
||||
private Phone mPhone;
|
||||
private CallEndpointSession mCallEndpointSession;
|
||||
private CallEndpointCallback mCallEndpointCallback;
|
||||
|
||||
public InCallService() {
|
||||
}
|
||||
@@ -494,6 +619,14 @@ public abstract class InCallService extends Service {
|
||||
onPhoneDestroyed(oldPhone);
|
||||
}
|
||||
|
||||
if (mCallEndpointCallback != null) {
|
||||
mCallEndpointCallback = null;
|
||||
}
|
||||
|
||||
if (mCallEndpointSession != null) {
|
||||
mCallEndpointSession = null;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -703,6 +836,21 @@ public abstract class InCallService extends Service {
|
||||
public void onConnectionEvent(Call call, String event, Bundle extras) {
|
||||
}
|
||||
|
||||
/**
|
||||
* To handle the request from telecom to activate an endpoint session. Streaming app with
|
||||
* meta-data {@link TelecomManager#METADATA_STREAMING_TETHERED_CALLS}.
|
||||
* @param endpoint The endpoint which is to be activated.
|
||||
* @param session An instance of {@link CallEndpointSession} to let streaming app report updates
|
||||
* of the endpoint.
|
||||
* @return CallEndpointCallback The implementation provided by streaming app. Telecom use this
|
||||
* to report events related to the call endpoint session.
|
||||
*/
|
||||
public @NonNull CallEndpointCallback onCallEndpointActivationRequested(
|
||||
@NonNull CallEndpoint endpoint, @NonNull CallEndpointSession session)
|
||||
throws UnsupportedOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to issue commands to the {@link Connection.VideoProvider} associated with a
|
||||
* {@link Call}.
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.telecom;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.net.Uri;
|
||||
@@ -29,8 +30,11 @@ import android.telecom.Call.Details.CallDirection;
|
||||
import com.android.internal.telecom.IVideoProvider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Information about a call that is used between InCallService and Telecom.
|
||||
@@ -69,6 +73,8 @@ public final class ParcelableCall implements Parcelable {
|
||||
private int mCallerNumberVerificationStatus;
|
||||
private String mContactDisplayName;
|
||||
private String mActiveChildCallId;
|
||||
private CallEndpoint mActiveCallEndpoint;
|
||||
private Set<CallEndpoint> mAvailableCallEndpoints = new HashSet<>();
|
||||
|
||||
public ParcelableCallBuilder setId(String id) {
|
||||
mId = id;
|
||||
@@ -224,6 +230,27 @@ public final class ParcelableCall implements Parcelable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set active call endpoint
|
||||
* @param callEndpoint
|
||||
* @return
|
||||
*/
|
||||
public ParcelableCallBuilder setActiveCallEndpoint(CallEndpoint callEndpoint) {
|
||||
mActiveCallEndpoint = callEndpoint;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set available call endpoints
|
||||
* @param availableCallEndpoints
|
||||
* @return
|
||||
*/
|
||||
public ParcelableCallBuilder setAvailableCallEndpoints(
|
||||
Set<CallEndpoint> availableCallEndpoints) {
|
||||
mAvailableCallEndpoints = availableCallEndpoints;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ParcelableCall createParcelableCall() {
|
||||
return new ParcelableCall(
|
||||
mId,
|
||||
@@ -255,7 +282,9 @@ public final class ParcelableCall implements Parcelable {
|
||||
mCallDirection,
|
||||
mCallerNumberVerificationStatus,
|
||||
mContactDisplayName,
|
||||
mActiveChildCallId);
|
||||
mActiveChildCallId,
|
||||
mActiveCallEndpoint,
|
||||
mAvailableCallEndpoints);
|
||||
}
|
||||
|
||||
public static ParcelableCallBuilder fromParcelableCall(ParcelableCall parcelableCall) {
|
||||
@@ -292,6 +321,8 @@ public final class ParcelableCall implements Parcelable {
|
||||
parcelableCall.mCallerNumberVerificationStatus;
|
||||
newBuilder.mContactDisplayName = parcelableCall.mContactDisplayName;
|
||||
newBuilder.mActiveChildCallId = parcelableCall.mActiveChildCallId;
|
||||
newBuilder.mActiveCallEndpoint = parcelableCall.mActiveCallEndpoint;
|
||||
newBuilder.mAvailableCallEndpoints = parcelableCall.mAvailableCallEndpoints;
|
||||
return newBuilder;
|
||||
}
|
||||
}
|
||||
@@ -327,6 +358,8 @@ public final class ParcelableCall implements Parcelable {
|
||||
private final int mCallerNumberVerificationStatus;
|
||||
private final String mContactDisplayName;
|
||||
private final String mActiveChildCallId; // Only valid for CDMA conferences
|
||||
private final CallEndpoint mActiveCallEndpoint;
|
||||
private final Set<CallEndpoint> mAvailableCallEndpoints;
|
||||
|
||||
public ParcelableCall(
|
||||
String id,
|
||||
@@ -358,7 +391,9 @@ public final class ParcelableCall implements Parcelable {
|
||||
int callDirection,
|
||||
int callerNumberVerificationStatus,
|
||||
String contactDisplayName,
|
||||
String activeChildCallId
|
||||
String activeChildCallId,
|
||||
CallEndpoint activeCallEndpoint,
|
||||
Set<CallEndpoint> availableCallEndpoints
|
||||
) {
|
||||
mId = id;
|
||||
mState = state;
|
||||
@@ -390,6 +425,8 @@ public final class ParcelableCall implements Parcelable {
|
||||
mCallerNumberVerificationStatus = callerNumberVerificationStatus;
|
||||
mContactDisplayName = contactDisplayName;
|
||||
mActiveChildCallId = activeChildCallId;
|
||||
mActiveCallEndpoint = activeCallEndpoint;
|
||||
mAvailableCallEndpoints = availableCallEndpoints;
|
||||
}
|
||||
|
||||
/** The unique ID of the call. */
|
||||
@@ -614,6 +651,21 @@ public final class ParcelableCall implements Parcelable {
|
||||
return mActiveChildCallId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The {@link CallEndpoint} which is currently active for this call, or null if the call
|
||||
* does not take place via an {@link CallEndpoint}.
|
||||
*/
|
||||
public @Nullable CallEndpoint getActiveCallEndpoint() {
|
||||
return mActiveCallEndpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A set of available {@link CallEndpoint}
|
||||
*/
|
||||
public @NonNull Set<CallEndpoint> getAvailableCallEndpoints() {
|
||||
return mAvailableCallEndpoints;
|
||||
}
|
||||
|
||||
/** Responsible for creating ParcelableCall objects for deserialized Parcels. */
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
||||
public static final @android.annotation.NonNull Parcelable.Creator<ParcelableCall> CREATOR =
|
||||
@@ -655,6 +707,9 @@ public final class ParcelableCall implements Parcelable {
|
||||
int callerNumberVerificationStatus = source.readInt();
|
||||
String contactDisplayName = source.readString();
|
||||
String activeChildCallId = source.readString();
|
||||
CallEndpoint activeCallEndpoint = source.readParcelable(classLoader);
|
||||
List<CallEndpoint> availablableCallEndpoints = new ArrayList<>();
|
||||
source.readList(availablableCallEndpoints, classLoader);
|
||||
return new ParcelableCallBuilder()
|
||||
.setId(id)
|
||||
.setState(state)
|
||||
@@ -686,6 +741,8 @@ public final class ParcelableCall implements Parcelable {
|
||||
.setCallerNumberVerificationStatus(callerNumberVerificationStatus)
|
||||
.setContactDisplayName(contactDisplayName)
|
||||
.setActiveChildCallId(activeChildCallId)
|
||||
.setActiveCallEndpoint(activeCallEndpoint)
|
||||
.setAvailableCallEndpoints(new HashSet<>(availablableCallEndpoints))
|
||||
.createParcelableCall();
|
||||
}
|
||||
|
||||
@@ -735,6 +792,8 @@ public final class ParcelableCall implements Parcelable {
|
||||
destination.writeInt(mCallerNumberVerificationStatus);
|
||||
destination.writeString(mContactDisplayName);
|
||||
destination.writeString(mActiveChildCallId);
|
||||
destination.writeParcelable(mActiveCallEndpoint, 0);
|
||||
destination.writeList(Arrays.asList(mAvailableCallEndpoints.toArray()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -292,6 +292,29 @@ public final class Phone {
|
||||
}
|
||||
}
|
||||
|
||||
void internalOnCallPullFailed(String callId, @Call.Callback.PullFailedReason int reason) {
|
||||
Call call = getCallById(callId);
|
||||
if (call != null) {
|
||||
call.internalOnCallPullFailed(reason);
|
||||
}
|
||||
}
|
||||
|
||||
void internalOnAnswerFailed(String callId, CallEndpoint callEndpoint,
|
||||
@Call.Callback.AnswerFailedReason int reason) {
|
||||
Call call = getCallById(callId);
|
||||
if (call != null) {
|
||||
call.internalOnAnswerFailed(callEndpoint, reason);
|
||||
}
|
||||
}
|
||||
|
||||
void internalOnCallPushFailed(String callId, CallEndpoint callEndpoint,
|
||||
@Call.Callback.PushFailedReason int reason) {
|
||||
Call call = getCallById(callId);
|
||||
if (call != null) {
|
||||
call.internalOnCallPushFailed(callEndpoint, reason);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to destroy the phone and cleanup any lingering calls.
|
||||
*/
|
||||
|
||||
@@ -54,8 +54,10 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
@@ -585,6 +587,14 @@ public class TelecomManager {
|
||||
public static final String EXTRA_START_CALL_WITH_RTT =
|
||||
"android.telecom.extra.START_CALL_WITH_RTT";
|
||||
|
||||
/**
|
||||
* A parcelable extra, which when set on the bundle passed into {@link #placeCall(Uri, Bundle)},
|
||||
* indicates that the call should be initiated with an active {@link CallEndpoint} to stream
|
||||
* the call as a tethered call.
|
||||
*/
|
||||
public static final String EXTRA_START_CALL_ON_ENDPOINT =
|
||||
"android.telecom.extra.START_CALL_ON_ENDPOINT";
|
||||
|
||||
/**
|
||||
* Start an activity indicating that the completion of an outgoing call or an incoming call
|
||||
* which was not blocked by the {@link CallScreeningService}, and which was NOT terminated
|
||||
@@ -744,6 +754,23 @@ public class TelecomManager {
|
||||
public static final String METADATA_INCLUDE_SELF_MANAGED_CALLS =
|
||||
"android.telecom.INCLUDE_SELF_MANAGED_CALLS";
|
||||
|
||||
/**
|
||||
* A boolean meta-data value indicating this {@link InCallService} implementation is aimed at
|
||||
* working as a streaming app for a tethered call. When there's a tethered call
|
||||
* requesting to a {@link CallEndpoint} registered with this app, Telecom will bind to this
|
||||
* streaming app and let the app streaming the call to the requested endpoint.
|
||||
* <p>
|
||||
* This meta-data can only be set for an {@link InCallService} which doesn't set neither
|
||||
* {@link #METADATA_IN_CALL_SERVICE_UI} nor {@link #METADATA_IN_CALL_SERVICE_CAR_MODE_UI}.
|
||||
* Otherwise, the app will be treated as a phone/dialer app or a car-mode app.
|
||||
* <p>
|
||||
* The {@link InCallService} declared this meta-data must implement
|
||||
* {@link InCallService#onCallEndpointActivationRequested(CallEndpoint, CallEndpointSession)}.
|
||||
* See this method for more information.
|
||||
*/
|
||||
public static final String METADATA_STREAMING_TETHERED_CALLS =
|
||||
"android.telecom.STREAMING_TETHERED_CALLS";
|
||||
|
||||
/**
|
||||
* The dual tone multi-frequency signaling character sent to indicate the dialing system should
|
||||
* pause for a predefined period.
|
||||
@@ -2250,6 +2277,7 @@ public class TelecomManager {
|
||||
* <li>{@link #EXTRA_PHONE_ACCOUNT_HANDLE}</li>
|
||||
* <li>{@link #EXTRA_START_CALL_WITH_SPEAKERPHONE}</li>
|
||||
* <li>{@link #EXTRA_START_CALL_WITH_VIDEO_STATE}</li>
|
||||
* <li>{@link #EXTRA_START_CALL_ON_ENDPOINT}</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* An app which implements the self-managed {@link ConnectionService} API uses
|
||||
@@ -2579,6 +2607,79 @@ public class TelecomManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a set of {@link CallEndpoint} to telecom. All registered {@link CallEndpoint} can
|
||||
* be provided as options for push, place or answer call externally.
|
||||
*
|
||||
* @param endpoints Endpoints to be registered.
|
||||
*/
|
||||
// TODO: add permission requirements
|
||||
// @RequiresPermission{}
|
||||
public void registerCallEndpoints(@NonNull Set<CallEndpoint> endpoints) {
|
||||
ITelecomService service = getTelecomService();
|
||||
List<CallEndpoint> endpointList = new ArrayList<>(endpoints);
|
||||
if (service != null) {
|
||||
try {
|
||||
service.registerCallEndpoints(endpointList, mContext.getOpPackageName());
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "RemoteException registerCallEndpoints: " + e);
|
||||
e.rethrowAsRuntimeException();
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException("Telecom service is null.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister all {@link CallEndpoint} from telecom in the set provided. After un-registration,
|
||||
* telecom will stop tracking and maintaining these {@link CallEndpoint}, user can no longer
|
||||
* carry a call on them.
|
||||
*
|
||||
* @param endpoints
|
||||
*/
|
||||
// TODO: add permission requirements
|
||||
// @RequiresPermission{}
|
||||
public void unregisterCallEndpoints(@NonNull Set<CallEndpoint> endpoints) {
|
||||
ITelecomService service = getTelecomService();
|
||||
List<CallEndpoint> endpointList = new ArrayList<>(endpoints);
|
||||
if (service != null) {
|
||||
try {
|
||||
service.unregisterCallEndpoints(endpointList, mContext.getOpPackageName());
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "RemoteException unregisterCallEndpoints: " + e);
|
||||
e.rethrowAsRuntimeException();
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException("Telecom service is null.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a set all registered {@link CallEndpoint} that can be used to stream and carry an
|
||||
* external call.
|
||||
*
|
||||
* @return A set of all available {@link CallEndpoint}.
|
||||
*/
|
||||
// TODO: add permission requirements
|
||||
// @RequiresPermission{}
|
||||
public @NonNull Set<CallEndpoint> getCallEndpoints() {
|
||||
Set<CallEndpoint> endpoints = new HashSet<>();
|
||||
List<CallEndpoint> endpointList;
|
||||
ITelecomService service = getTelecomService();
|
||||
if (service != null) {
|
||||
try {
|
||||
endpointList = service.getCallEndpoints(mContext.getOpPackageName());
|
||||
return new HashSet<>(endpointList);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "RemoteException registerCallEndpoints: " + e);
|
||||
e.rethrowAsRuntimeException();
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException("Telecom service is null.");
|
||||
}
|
||||
return endpoints;
|
||||
}
|
||||
|
||||
private boolean isSystemProcess() {
|
||||
return Process.myUid() == Process.SYSTEM_UID;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 com.android.internal.telecom;
|
||||
|
||||
/**
|
||||
* Internal remote CallEndpointCallback interface for Telecom framework to report event related to
|
||||
* the endpoint session.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
oneway interface ICallEndpointCallback {
|
||||
void onCallEndpointSessionActivationTimeout();
|
||||
|
||||
void onCallEndpointSessionDeactivated();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 com.android.internal.telecom;
|
||||
|
||||
/**
|
||||
* Internal remote CallEndpointSession interface for streaming app to update the status of the
|
||||
* endpoint.
|
||||
*
|
||||
* @see android.telecom.CallEndpointSession
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
|
||||
oneway interface ICallEndpointSession {
|
||||
void setCallEndpointSessionActivated();
|
||||
|
||||
void setCallEndpointSessionActivationFailed(int reason);
|
||||
|
||||
void setCallEndpointSessionDeactivated();
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.telecom.CallAudioState;
|
||||
import android.telecom.CallEndpoint;
|
||||
import android.telecom.Connection;
|
||||
import android.telecom.ConnectionRequest;
|
||||
import android.telecom.Logging.Session;
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.internal.telecom;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.telecom.CallEndpoint;
|
||||
import android.telecom.PhoneAccountHandle;
|
||||
|
||||
/**
|
||||
@@ -95,4 +96,8 @@ oneway interface IInCallAdapter {
|
||||
|
||||
void handoverTo(String callId, in PhoneAccountHandle destAcct, int videoState,
|
||||
in Bundle extras);
|
||||
|
||||
void pushCall(String callId, in CallEndpoint endpoint);
|
||||
|
||||
void answerCallViaEndpoint(String callId, in CallEndpoint endpoint, int videoState);
|
||||
}
|
||||
|
||||
@@ -19,9 +19,12 @@ package com.android.internal.telecom;
|
||||
import android.app.PendingIntent;
|
||||
import android.os.Bundle;
|
||||
import android.telecom.CallAudioState;
|
||||
import android.telecom.CallEndpoint;
|
||||
import android.telecom.ParcelableCall;
|
||||
|
||||
import com.android.internal.telecom.IInCallAdapter;
|
||||
import com.android.internal.telecom.ICallEndpointCallback;
|
||||
import com.android.internal.telecom.ICallEndpointSession;
|
||||
|
||||
/**
|
||||
* Internal remote interface for in-call services.
|
||||
@@ -30,9 +33,12 @@ import com.android.internal.telecom.IInCallAdapter;
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
oneway interface IInCallService {
|
||||
interface IInCallService {
|
||||
void setInCallAdapter(in IInCallAdapter inCallAdapter);
|
||||
|
||||
ICallEndpointCallback requestCallEndpointActivation(in CallEndpoint callEndpoint,
|
||||
in ICallEndpointSession callEndpointSession);
|
||||
|
||||
void addCall(in ParcelableCall call);
|
||||
|
||||
void updateCall(in ParcelableCall call);
|
||||
@@ -58,4 +64,10 @@ oneway interface IInCallService {
|
||||
void onHandoverFailed(String callId, int error);
|
||||
|
||||
void onHandoverComplete(String callId);
|
||||
|
||||
void onCallPullFailed(String callId, int reason);
|
||||
|
||||
void onCallPushFailed(String callId, in CallEndpoint endpoint, int reason);
|
||||
|
||||
void onAnswerFailed(String callId, in CallEndpoint endpoint, int reason);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.internal.telecom;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.telecom.CallEndpoint;
|
||||
import android.telecom.TelecomAnalytics;
|
||||
import android.telecom.PhoneAccountHandle;
|
||||
import android.net.Uri;
|
||||
@@ -368,4 +369,19 @@ interface ITelecomService {
|
||||
* @see TelecomServiceImpl#setTestCallDiagnosticService
|
||||
*/
|
||||
void setTestCallDiagnosticService(in String packageName);
|
||||
|
||||
/**
|
||||
* @see TelecomServiceImpl#registerCallEndpoints(in List<CallEndpoint>, in String);
|
||||
*/
|
||||
void registerCallEndpoints(in List<CallEndpoint> endpoints, in String packageName);
|
||||
|
||||
/**
|
||||
* @see TelecomServiceImpl#unregisterCallEndpoints(in List<CallEndpoint>, String);
|
||||
*/
|
||||
void unregisterCallEndpoints(in List<CallEndpoint> endpoints, in String packageName);
|
||||
|
||||
/**
|
||||
* @see TelecomServiceImpl#getCallEndpoints(in String packageName);
|
||||
*/
|
||||
List<CallEndpoint> getCallEndpoints(in String packageName);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user