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
This commit is contained in:
Ihab Awad
2014-06-03 18:40:45 -07:00
parent 94236c56dd
commit fc91b7d448
9 changed files with 196 additions and 34 deletions

View File

@@ -27465,6 +27465,7 @@ package android.telephony {
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
@@ -27477,6 +27478,8 @@ package android.telephony {
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
@@ -27487,12 +27490,13 @@ package android.telephony {
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
@@ -27501,6 +27505,7 @@ package android.telephony {
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 {

View File

@@ -84,12 +84,16 @@ public final class CallServiceAdapter {
/**
* 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) {
}
}

View File

@@ -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;

View File

@@ -18,23 +18,37 @@ package android.telecomm;
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 @@ public final class ConnectionRequest {
: 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);
}}

View File

@@ -18,6 +18,7 @@ package android.telecomm;
import android.net.Uri;
import android.os.Bundle;
import android.telephony.DisconnectCause;
import java.util.HashMap;
import java.util.LinkedList;
@@ -115,9 +116,8 @@ public abstract class ConnectionService extends CallService {
}
@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 @@ public abstract class ConnectionService extends CallService {
Log.d(this, "call %s", callInfo);
onCreateConnections(
new ConnectionRequest(
callInfo.getId(),
callInfo.getHandle(),
callInfo.getExtras()),
new Response<ConnectionRequest, Connection>() {
@@ -137,7 +138,8 @@ public abstract class ConnectionService extends CallService {
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 @@ public abstract class ConnectionService extends CallService {
}
@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 @@ public abstract class ConnectionService extends CallService {
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 @@ public abstract class ConnectionService extends CallService {
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 @@ public abstract class ConnectionService extends CallService {
}
@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);
}
}
);

View File

@@ -31,7 +31,8 @@ import java.util.List;
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 final class InCallCall implements Parcelable {
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 final class InCallCall implements Parcelable {
public InCallCall(
String id,
CallState state,
int disconnectCause,
int disconnectCauseCode,
String disconnectCauseMsg,
int capabilities,
long connectTimeMillis,
Uri handle,
@@ -75,7 +78,8 @@ public final class InCallCall implements Parcelable {
List<String> childCallIds) {
mId = id;
mState = state;
mDisconnectCause = disconnectCause;
mDisconnectCauseCode = disconnectCauseCode;
mDisconnectCauseMsg = disconnectCauseMsg;
mCapabilities = capabilities;
mConnectTimeMillis = connectTimeMillis;
mHandle = handle;
@@ -101,8 +105,16 @@ public final class InCallCall implements Parcelable {
* 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 final class InCallCall implements Parcelable {
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 @@ public final class InCallCall implements Parcelable {
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 final class InCallCall implements Parcelable {
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);

View File

@@ -33,7 +33,8 @@ public interface Response<IN, OUT> {
* 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);
}

View File

@@ -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 @@ oneway interface ICallServiceAdapter {
void handleSuccessfulOutgoingCall(String callId);
void handleFailedOutgoingCall(String callId, String errorMessage);
void handleFailedOutgoingCall(in ConnectionRequest request, int errorCode, String errorMessage);
void setActive(String callId);

View File

@@ -97,11 +97,62 @@ public class DisconnectCause {
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 @@ public class DisconnectCause {
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: