DO NOT MERGE. Implement connection error dialogs (1/4)
Implement reporting of connection errors from ConnectionServices through
Telecomm to the InCallUI.
Bug: 15195720
Bug: 15117141
Change-Id: I0e1443f75a175a212fb19afde5a7eadef15d239d
(cherry picked from commit 976bfe497da31fa8322969648ffbe77898941d0c)
diff --git a/api/current.txt b/api/current.txt
index 0c18c56..078cdc5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -27596,7 +27596,7 @@
}
public final class CallServiceAdapter {
- method public void handleFailedOutgoingCall(java.lang.String, java.lang.String);
+ method public void handleFailedOutgoingCall(android.telecomm.ConnectionRequest, int, java.lang.String);
method public void handleSuccessfulOutgoingCall(java.lang.String);
method public void notifyIncomingCall(android.telecomm.CallInfo);
method public void setActive(java.lang.String);
@@ -27723,10 +27723,15 @@
field public static final int RINGING = 1; // 0x1
}
- public final class ConnectionRequest {
+ public final class ConnectionRequest implements android.os.Parcelable {
ctor public ConnectionRequest(android.net.Uri, android.os.Bundle);
+ ctor public ConnectionRequest(java.lang.String, android.net.Uri, android.os.Bundle);
+ method public int describeContents();
+ method public java.lang.String getCallId();
method public android.os.Bundle getExtras();
method public android.net.Uri getHandle();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator CREATOR;
}
public abstract class ConnectionService extends android.telecomm.CallService {
@@ -27777,7 +27782,8 @@
method public int getCapabilities();
method public long getConnectTimeMillis();
method public android.telecomm.CallServiceDescriptor getCurrentCallServiceDescriptor();
- method public int getDisconnectCause();
+ method public int getDisconnectCauseCode();
+ method public java.lang.String getDisconnectCauseMsg();
method public android.telecomm.GatewayInfo getGatewayInfo();
method public android.net.Uri getHandle();
method public android.telecomm.CallServiceDescriptor getHandoffCallServiceDescriptor();
@@ -27801,7 +27807,7 @@
}
public abstract interface Response {
- method public abstract void onError(IN, java.lang.String);
+ method public abstract void onError(IN, int, java.lang.String);
method public abstract void onResult(IN, OUT...);
}
@@ -27982,6 +27988,7 @@
field public static final int CALL_BARRED = 20; // 0x14
field public static final int CDMA_ACCESS_BLOCKED = 35; // 0x23
field public static final int CDMA_ACCESS_FAILURE = 32; // 0x20
+ field public static final int CDMA_CALL_LOST = 41; // 0x29
field public static final int CDMA_DROP = 27; // 0x1b
field public static final int CDMA_INTERCEPT = 28; // 0x1c
field public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 26; // 0x1a
@@ -27994,6 +28001,8 @@
field public static final int CS_RESTRICTED = 22; // 0x16
field public static final int CS_RESTRICTED_EMERGENCY = 24; // 0x18
field public static final int CS_RESTRICTED_NORMAL = 23; // 0x17
+ field public static final int DIALED_MMI = 39; // 0x27
+ field public static final int EMERGENCY_ONLY = 37; // 0x25
field public static final int ERROR_UNSPECIFIED = 36; // 0x24
field public static final int FDN_BLOCKED = 21; // 0x15
field public static final int ICC_ERROR = 19; // 0x13
@@ -28004,12 +28013,13 @@
field public static final int LIMIT_EXCEEDED = 15; // 0xf
field public static final int LOCAL = 3; // 0x3
field public static final int LOST_SIGNAL = 14; // 0xe
- field public static final int MAXIMUM_VALID_VALUE = 36; // 0x24
+ field public static final int MAXIMUM_VALID_VALUE = 42; // 0x2a
field public static final int MINIMUM_VALID_VALUE = 0; // 0x0
field public static final int MMI = 6; // 0x6
field public static final int NORMAL = 2; // 0x2
field public static final int NOT_DISCONNECTED = 0; // 0x0
field public static final int NOT_VALID = -1; // 0xffffffff
+ field public static final int NO_PHONE_NUMBER_SUPPLIED = 38; // 0x26
field public static final int NUMBER_UNREACHABLE = 8; // 0x8
field public static final int OUT_OF_NETWORK = 11; // 0xb
field public static final int OUT_OF_SERVICE = 18; // 0x12
@@ -28018,6 +28028,7 @@
field public static final int SERVER_UNREACHABLE = 9; // 0x9
field public static final int TIMED_OUT = 13; // 0xd
field public static final int UNOBTAINABLE_NUMBER = 25; // 0x19
+ field public static final int VOICEMAIL_NUMBER_MISSING = 40; // 0x28
}
public class NeighboringCellInfo implements android.os.Parcelable {
diff --git a/telecomm/java/android/telecomm/CallServiceAdapter.java b/telecomm/java/android/telecomm/CallServiceAdapter.java
index 7396808..0c57828 100644
--- a/telecomm/java/android/telecomm/CallServiceAdapter.java
+++ b/telecomm/java/android/telecomm/CallServiceAdapter.java
@@ -84,12 +84,16 @@
/**
* Tells Telecomm that an attempt to place the specified outgoing call failed.
*
- * @param callId The ID of the outgoing call.
- * @param errorMessage The error associated with the failed call attempt.
+ * @param request The originating request for a connection.
+ * @param errorCode The error code associated with the failed call attempt.
+ * @param errorMsg The error message associated with the failed call attempt.
*/
- public void handleFailedOutgoingCall(String callId, String errorMessage) {
+ public void handleFailedOutgoingCall(
+ ConnectionRequest request,
+ int errorCode,
+ String errorMsg) {
try {
- mAdapter.handleFailedOutgoingCall(callId, errorMessage);
+ mAdapter.handleFailedOutgoingCall(request, errorCode, errorMsg);
} catch (RemoteException e) {
}
}
diff --git a/telecomm/java/android/telecomm/ConnectionRequest.aidl b/telecomm/java/android/telecomm/ConnectionRequest.aidl
new file mode 100644
index 0000000..72e5c8c
--- /dev/null
+++ b/telecomm/java/android/telecomm/ConnectionRequest.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2014, 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.telecomm;
+
+parcelable ConnectionRequest;
diff --git a/telecomm/java/android/telecomm/ConnectionRequest.java b/telecomm/java/android/telecomm/ConnectionRequest.java
index c1f1871..bf5727b 100644
--- a/telecomm/java/android/telecomm/ConnectionRequest.java
+++ b/telecomm/java/android/telecomm/ConnectionRequest.java
@@ -18,23 +18,37 @@
import android.os.Bundle;
import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
/**
* Simple data container encapsulating a request to some entity to
* create a new {@link Connection}.
*/
-public final class ConnectionRequest {
+public final class ConnectionRequest implements Parcelable {
// TODO: Token to limit recursive invocations
// TODO: Consider upgrading "mHandle" to ordered list of handles, indicating a set of phone
// numbers that would satisfy the client's needs, in order of preference
+ private final String mCallId;
private final Uri mHandle;
private final Bundle mExtras;
public ConnectionRequest(Uri handle, Bundle extras) {
- mHandle = handle; mExtras = extras;
+ this(null, handle, extras);
}
+ public ConnectionRequest(String callId, Uri handle, Bundle extras) {
+ mCallId = callId;
+ mHandle = handle;
+ mExtras = extras;
+ }
+
+ /**
+ * An identifier for this call.
+ */
+ public String getCallId() { return mCallId; }
+
/**
* The handle (e.g., phone number) to which the {@link Connection} is to connect.
*/
@@ -54,4 +68,40 @@
: ConnectionService.toLogSafePhoneNumber(mHandle.toString()),
mExtras == null ? "" : mExtras);
}
-}
+
+ /**
+ * Responsible for creating CallInfo objects for deserialized Parcels.
+ */
+ public static final Parcelable.Creator<ConnectionRequest> CREATOR =
+ new Parcelable.Creator<ConnectionRequest> () {
+ @Override
+ public ConnectionRequest createFromParcel(Parcel source) {
+ String callId = source.readString();
+ Uri handle = (Uri) source.readParcelable(getClass().getClassLoader());
+ Bundle extras = (Bundle) source.readParcelable(getClass().getClassLoader());
+ return new ConnectionRequest(callId, handle, extras);
+ }
+
+ @Override
+ public ConnectionRequest[] newArray(int size) {
+ return new ConnectionRequest[size];
+ }
+ };
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Writes CallInfo object into a serializeable Parcel.
+ */
+ @Override
+ public void writeToParcel(Parcel destination, int flags) {
+ destination.writeString(mCallId);
+ destination.writeParcelable(mHandle, 0);
+ destination.writeParcelable(mExtras, 0);
+ }}
diff --git a/telecomm/java/android/telecomm/ConnectionService.java b/telecomm/java/android/telecomm/ConnectionService.java
index aeb1c33..31de15c 100644
--- a/telecomm/java/android/telecomm/ConnectionService.java
+++ b/telecomm/java/android/telecomm/ConnectionService.java
@@ -18,6 +18,7 @@
import android.net.Uri;
import android.os.Bundle;
+import android.telephony.DisconnectCause;
import java.util.HashMap;
import java.util.LinkedList;
@@ -115,9 +116,8 @@
}
@Override
- public void onError(Uri handle, String reason) {
- Log.w(this, "Error in onFindSubscriptions " + callInfo.getHandle()
- + " error: " + reason);
+ public void onError(Uri handle, int code, String msg) {
+ Log.w(this, "Error in onFindSubscriptions %s %d %s", handle, code, msg);
getAdapter().setIsCompatibleWith(callInfo.getId(), false);
}
}
@@ -129,6 +129,7 @@
Log.d(this, "call %s", callInfo);
onCreateConnections(
new ConnectionRequest(
+ callInfo.getId(),
callInfo.getHandle(),
callInfo.getExtras()),
new Response<ConnectionRequest, Connection>() {
@@ -137,7 +138,8 @@
if (result.length != 1) {
Log.d(this, "adapter handleFailedOutgoingCall %s", callInfo);
getAdapter().handleFailedOutgoingCall(
- callInfo.getId(),
+ request,
+ DisconnectCause.ERROR_UNSPECIFIED,
"Created " + result.length + " Connections, expected 1");
for (Connection c : result) {
c.abort();
@@ -150,8 +152,8 @@
}
@Override
- public void onError(ConnectionRequest request, String reason) {
- getAdapter().handleFailedOutgoingCall(callInfo.getId(), reason);
+ public void onError(ConnectionRequest request, int code, String msg) {
+ getAdapter().handleFailedOutgoingCall(request, code, msg);
}
}
);
@@ -168,6 +170,7 @@
Log.d(this, "setIncomingCallId %s %s", callId, extras);
onCreateIncomingConnection(
new ConnectionRequest(
+ callId,
null, // TODO: Can we obtain this from "extras"?
extras),
new Response<ConnectionRequest, Connection>() {
@@ -176,7 +179,8 @@
if (result.length != 1) {
Log.d(this, "adapter handleFailedOutgoingCall %s", callId);
getAdapter().handleFailedOutgoingCall(
- callId,
+ request,
+ DisconnectCause.ERROR_UNSPECIFIED,
"Created " + result.length + " Connections, expected 1");
for (Connection c : result) {
c.abort();
@@ -195,8 +199,9 @@
}
@Override
- public void onError(ConnectionRequest request, String reason) {
- Log.d(this, "adapter failed setIncomingCallId %s %s", request, reason);
+ public void onError(ConnectionRequest request, int code, String msg) {
+ Log.d(this, "adapter failed setIncomingCallId %s %d %s",
+ request, code, msg);
}
}
);
diff --git a/telecomm/java/android/telecomm/InCallCall.java b/telecomm/java/android/telecomm/InCallCall.java
index 346d207..b531ccd 100644
--- a/telecomm/java/android/telecomm/InCallCall.java
+++ b/telecomm/java/android/telecomm/InCallCall.java
@@ -31,7 +31,8 @@
public final class InCallCall implements Parcelable {
private final String mId;
private final CallState mState;
- private final int mDisconnectCause;
+ private final int mDisconnectCauseCode;
+ private final String mDisconnectCauseMsg;
private final int mCapabilities;
private final long mConnectTimeMillis;
private final Uri mHandle;
@@ -47,15 +48,16 @@
public InCallCall(
String id,
CallState state,
- int disconnectCause,
+ int disconnectCauseCode,
+ String disconnectCauseMsg,
int capabilities,
long connectTimeMillis,
Uri handle,
GatewayInfo gatewayInfo,
CallServiceDescriptor descriptor,
CallServiceDescriptor handoffDescriptor) {
- this(id, state, disconnectCause, capabilities, connectTimeMillis, handle, gatewayInfo,
- descriptor, handoffDescriptor, Collections.EMPTY_LIST, null,
+ this(id, state, disconnectCauseCode, disconnectCauseMsg, capabilities, connectTimeMillis,
+ handle, gatewayInfo, descriptor, handoffDescriptor, Collections.EMPTY_LIST, null,
Collections.EMPTY_LIST);
}
@@ -63,7 +65,8 @@
public InCallCall(
String id,
CallState state,
- int disconnectCause,
+ int disconnectCauseCode,
+ String disconnectCauseMsg,
int capabilities,
long connectTimeMillis,
Uri handle,
@@ -75,7 +78,8 @@
List<String> childCallIds) {
mId = id;
mState = state;
- mDisconnectCause = disconnectCause;
+ mDisconnectCauseCode = disconnectCauseCode;
+ mDisconnectCauseMsg = disconnectCauseMsg;
mCapabilities = capabilities;
mConnectTimeMillis = connectTimeMillis;
mHandle = handle;
@@ -101,8 +105,16 @@
* Reason for disconnection, values are defined in {@link DisconnectCause}. Valid when call
* state is {@link CallState#DISCONNECTED}.
*/
- public int getDisconnectCause() {
- return mDisconnectCause;
+ public int getDisconnectCauseCode() {
+ return mDisconnectCauseCode;
+ }
+
+ /**
+ * Further optional textual information about the reason for disconnection. Valid when call
+ * state is {@link CallState#DISCONNECTED}.
+ */
+ public String getDisconnectCauseMsg() {
+ return mDisconnectCauseMsg;
}
// Bit mask of actions a call supports, values are defined in {@link CallCapabilities}.
@@ -170,7 +182,8 @@
public InCallCall createFromParcel(Parcel source) {
String id = source.readString();
CallState state = CallState.valueOf(source.readString());
- int disconnectCause = source.readInt();
+ int disconnectCauseCode = source.readInt();
+ String disconnectCauseMsg = source.readString();
int capabilities = source.readInt();
long connectTimeMillis = source.readLong();
ClassLoader classLoader = InCallCall.class.getClassLoader();
@@ -183,9 +196,9 @@
String parentCallId = source.readString();
List<String> childCallIds = new ArrayList<>();
source.readList(childCallIds, classLoader);
- return new InCallCall(id, state, disconnectCause, capabilities, connectTimeMillis,
- handle, gatewayInfo, descriptor, handoffDescriptor, conferenceCapableCallIds,
- parentCallId, childCallIds);
+ return new InCallCall(id, state, disconnectCauseCode, disconnectCauseMsg, capabilities,
+ connectTimeMillis, handle, gatewayInfo, descriptor, handoffDescriptor,
+ conferenceCapableCallIds, parentCallId, childCallIds);
}
@Override
@@ -205,7 +218,8 @@
public void writeToParcel(Parcel destination, int flags) {
destination.writeString(mId);
destination.writeString(mState.name());
- destination.writeInt(mDisconnectCause);
+ destination.writeInt(mDisconnectCauseCode);
+ destination.writeString(mDisconnectCauseMsg);
destination.writeInt(mCapabilities);
destination.writeLong(mConnectTimeMillis);
destination.writeParcelable(mHandle, 0);
diff --git a/telecomm/java/android/telecomm/Response.java b/telecomm/java/android/telecomm/Response.java
index 14f8340..13c0702 100644
--- a/telecomm/java/android/telecomm/Response.java
+++ b/telecomm/java/android/telecomm/Response.java
@@ -33,7 +33,8 @@
* Indicates the inability to provide results.
*
* @param request The original request.
- * @param reason The reason for the failure.
+ * @param code An integer code indicating the reason for failure.
+ * @param msg A message explaining the reason for failure.
*/
- void onError(IN request, String reason);
+ void onError(IN request, int code, String msg);
}
diff --git a/telecomm/java/com/android/internal/telecomm/ICallServiceAdapter.aidl b/telecomm/java/com/android/internal/telecomm/ICallServiceAdapter.aidl
index a92b176..f94eb32 100644
--- a/telecomm/java/com/android/internal/telecomm/ICallServiceAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecomm/ICallServiceAdapter.aidl
@@ -17,6 +17,7 @@
package com.android.internal.telecomm;
import android.telecomm.CallInfo;
+import android.telecomm.ConnectionRequest;
/**
* Internal remote callback interface for call services.
@@ -32,7 +33,7 @@
void handleSuccessfulOutgoingCall(String callId);
- void handleFailedOutgoingCall(String callId, String errorMessage);
+ void handleFailedOutgoingCall(in ConnectionRequest request, int errorCode, String errorMessage);
void setActive(String callId);
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index 8681344..d2044be 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -97,11 +97,62 @@
public static final int CDMA_ACCESS_BLOCKED = 35;
/** Unknown error or not specified */
public static final int ERROR_UNSPECIFIED = 36;
+ /**
+ * Only emergency numbers are allowed, but we tried to dial
+ * a non-emergency number.
+ */
+ // TODO: This should be the same as NOT_EMERGENCY
+ public static final int EMERGENCY_ONLY = 37;
+ /**
+ * The supplied CALL Intent didn't contain a valid phone number.
+ */
+ public static final int NO_PHONE_NUMBER_SUPPLIED = 38;
+ /**
+ * Our initial phone number was actually an MMI sequence.
+ */
+ public static final int DIALED_MMI = 39;
+ /**
+ * We tried to call a voicemail: URI but the device has no
+ * voicemail number configured.
+ */
+ public static final int VOICEMAIL_NUMBER_MISSING = 40;
+ /**
+ * This status indicates that InCallScreen should display the
+ * CDMA-specific "call lost" dialog. (If an outgoing call fails,
+ * and the CDMA "auto-retry" feature is enabled, *and* the retried
+ * call fails too, we display this specific dialog.)
+ *
+ * TODO: this is currently unused, since the "call lost" dialog
+ * needs to be triggered by a *disconnect* event, rather than when
+ * the InCallScreen first comes to the foreground. For now we use
+ * the needToShowCallLostDialog field for this (see below.)
+ */
+ public static final int CDMA_CALL_LOST = 41;
+ /**
+ * This status indicates that the call was placed successfully,
+ * but additionally, the InCallScreen needs to display the
+ * "Exiting ECM" dialog.
+ *
+ * (Details: "Emergency callback mode" is a CDMA-specific concept
+ * where the phone disallows data connections over the cell
+ * network for some period of time after you make an emergency
+ * call. If the phone is in ECM and you dial a non-emergency
+ * number, that automatically *cancels* ECM, but we additionally
+ * need to warn the user that ECM has been canceled (see bug
+ * 4207607.))
+ *
+ * TODO: Rethink where the best place to put this is. It is not a notification
+ * of a failure of the connection -- it is an additional message that accompanies
+ * a successful connection giving the user important information about what happened.
+ *
+ * {@hide}
+ */
+ public static final int EXITED_ECM = 42;
/** Smallest valid value for call disconnect codes. */
public static final int MINIMUM_VALID_VALUE = NOT_DISCONNECTED;
/** Largest valid value for call disconnect codes. */
- public static final int MAXIMUM_VALID_VALUE = ERROR_UNSPECIFIED;
+ public static final int MAXIMUM_VALID_VALUE = EXITED_ECM;
/** Private constructor to avoid class instantiation. */
private DisconnectCause() {
@@ -181,6 +232,18 @@
return "CDMA_NOT_EMERGENCY";
case CDMA_ACCESS_BLOCKED:
return "CDMA_ACCESS_BLOCKED";
+ case EMERGENCY_ONLY:
+ return "EMERGENCY_ONLY";
+ case NO_PHONE_NUMBER_SUPPLIED:
+ return "NO_PHONE_NUMBER_SUPPLIED";
+ case DIALED_MMI:
+ return "DIALED_MMI";
+ case VOICEMAIL_NUMBER_MISSING:
+ return "VOICEMAIL_NUMBER_MISSING";
+ case CDMA_CALL_LOST:
+ return "CDMA_CALL_LOST";
+ case EXITED_ECM:
+ return "EXITED_ECM";
case ERROR_UNSPECIFIED:
return "ERROR_UNSPECIFIED";
default: