Merge "Remove ability to enable/disable phoneaccounts (2/6)" into lmp-dev
diff --git a/sip/src/com/android/services/telephony/sip/SipConnection.java b/sip/src/com/android/services/telephony/sip/SipConnection.java
index f6089b7..a858035 100644
--- a/sip/src/com/android/services/telephony/sip/SipConnection.java
+++ b/sip/src/com/android/services/telephony/sip/SipConnection.java
@@ -21,6 +21,7 @@
 import android.os.Message;
 import android.telecom.AudioState;
 import android.telecom.Connection;
+import android.telecom.DisconnectCause;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneCapabilities;
 import android.util.Log;
@@ -28,6 +29,7 @@
 import com.android.internal.telephony.Call;
 import com.android.internal.telephony.CallStateException;
 import com.android.internal.telephony.sip.SipPhone;
+import com.android.services.telephony.DisconnectCauseUtil;
 
 import java.util.Objects;
 
@@ -232,7 +234,8 @@
                     setRinging();
                     break;
                 case DISCONNECTED:
-                    setDisconnected(mOriginalConnection.getDisconnectCause(), null);
+                    setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(
+                            mOriginalConnection.getDisconnectCause()));
                     close();
                     break;
                 case DISCONNECTING:
diff --git a/sip/src/com/android/services/telephony/sip/SipConnectionService.java b/sip/src/com/android/services/telephony/sip/SipConnectionService.java
index 4060e11..a53a336 100644
--- a/sip/src/com/android/services/telephony/sip/SipConnectionService.java
+++ b/sip/src/com/android/services/telephony/sip/SipConnectionService.java
@@ -39,6 +39,7 @@
 import com.android.internal.telephony.CallStateException;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.sip.SipPhone;
+import com.android.services.telephony.DisconnectCauseUtil;
 
 import java.util.List;
 import java.util.Objects;
@@ -70,15 +71,15 @@
         Bundle extras = request.getExtras();
         if (extras != null &&
                 extras.getString(TelecomManager.GATEWAY_PROVIDER_PACKAGE) != null) {
-            return Connection.createFailedConnection(
-                    DisconnectCause.CALL_BARRED, "Cannot make a SIP call with a gateway number.");
+            return Connection.createFailedConnection(DisconnectCauseUtil.toTelecomDisconnectCause(
+                    DisconnectCause.CALL_BARRED, "Cannot make a SIP call with a gateway number."));
         }
 
         PhoneAccountHandle accountHandle = request.getAccountHandle();
         ComponentName sipComponentName = new ComponentName(this, SipConnectionService.class);
         if (!Objects.equals(accountHandle.getComponentName(), sipComponentName)) {
-            return Connection.createFailedConnection(
-                    DisconnectCause.OUTGOING_FAILURE, "Did not match service connection");
+            return Connection.createFailedConnection(DisconnectCauseUtil.toTelecomDisconnectCause(
+                    DisconnectCause.OUTGOING_FAILURE, "Did not match service connection"));
         }
 
         final SipConnection connection = new SipConnection();
@@ -91,8 +92,8 @@
             SipProfileChooserDialogs.showNoVoip(this, new ResultReceiver(mHandler) {
                     @Override
                     protected void onReceiveResult(int choice, Bundle resultData) {
-                        connection.setDisconnected(
-                                DisconnectCause.ERROR_UNSPECIFIED, "VoIP unsupported");
+                        connection.setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(
+                                DisconnectCause.ERROR_UNSPECIFIED, "VoIP unsupported"));
                     }
             });
             attemptCall = false;
@@ -103,7 +104,8 @@
             SipProfileChooserDialogs.showNoInternetError(this, new ResultReceiver(mHandler) {
                     @Override
                     protected void onReceiveResult(int choice, Bundle resultData) {
-                        connection.setDisconnected(DisconnectCause.OUT_OF_SERVICE, null);
+                        connection.setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(
+                                DisconnectCause.OUT_OF_SERVICE, "Network not connected."));
                     }
             });
             attemptCall = false;
@@ -117,15 +119,15 @@
                 @Override
                 public void onFound(SipProfile profile) {
                     if (profile == null) {
-                        connection.setDisconnected(
-                                DisconnectCause.OUTGOING_FAILURE, "SIP profile not found.");
+                        connection.setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(
+                                DisconnectCause.OUTGOING_FAILURE, "SIP profile not found."));
                         connection.destroy();
                     } else {
                         com.android.internal.telephony.Connection chosenConnection =
                                 createConnectionForProfile(profile, request);
                         if (chosenConnection == null) {
-                            connection.setDisconnected(
-                                    DisconnectCause.OUTGOING_FAILURE, "Connection failed.");
+                            connection.setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(
+                                    DisconnectCause.OUTGOING_FAILURE, "Connection failed."));
                             connection.destroy();
                         } else {
                             if (VERBOSE) log("initializing connection");
@@ -147,14 +149,16 @@
 
         if (request.getExtras() == null) {
             if (VERBOSE) log("onCreateIncomingConnection, no extras");
-            return Connection.createFailedConnection(DisconnectCause.ERROR_UNSPECIFIED, null);
+            return Connection.createFailedConnection(DisconnectCauseUtil.toTelecomDisconnectCause(
+                    DisconnectCause.ERROR_UNSPECIFIED, "No extras on request."));
         }
 
         Intent sipIntent = (Intent) request.getExtras().getParcelable(
                 SipUtil.EXTRA_INCOMING_CALL_INTENT);
         if (sipIntent == null) {
             if (VERBOSE) log("onCreateIncomingConnection, no SIP intent");
-            return Connection.createFailedConnection(DisconnectCause.ERROR_UNSPECIFIED, null);
+            return Connection.createFailedConnection(DisconnectCauseUtil.toTelecomDisconnectCause(
+                    DisconnectCause.ERROR_UNSPECIFIED, "No SIP intent."));
         }
 
         SipAudioCall sipAudioCall;
@@ -183,7 +187,8 @@
                 return Connection.createCanceledConnection();
             }
         }
-        return Connection.createFailedConnection(DisconnectCause.ERROR_UNSPECIFIED, null);
+        return Connection.createFailedConnection(DisconnectCauseUtil.toTelecomDisconnectCause(
+                DisconnectCause.ERROR_UNSPECIFIED));
     }
 
     private com.android.internal.telephony.Connection createConnectionForProfile(
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index d373b60..5380fa5 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -578,41 +578,6 @@
         // earpiece) after a call disconnects.
         int toneToPlay = InCallTonePlayer.TONE_NONE;
 
-        // The "Busy" or "Congestion" tone is the highest priority:
-        if (c != null) {
-            int cause = c.getDisconnectCause();
-            if (cause == DisconnectCause.BUSY) {
-                if (DBG) log("- need to play BUSY tone!");
-                toneToPlay = InCallTonePlayer.TONE_BUSY;
-            } else if (cause == DisconnectCause.CONGESTION) {
-                if (DBG) log("- need to play CONGESTION tone!");
-                toneToPlay = InCallTonePlayer.TONE_CONGESTION;
-            } else if (((cause == DisconnectCause.NORMAL)
-                    || (cause == DisconnectCause.LOCAL))
-                    && (mApplication.isOtaCallInActiveState())) {
-                if (DBG) log("- need to play OTA_CALL_END tone!");
-                toneToPlay = InCallTonePlayer.TONE_OTA_CALL_END;
-            } else if (cause == DisconnectCause.CDMA_REORDER) {
-                if (DBG) log("- need to play CDMA_REORDER tone!");
-                toneToPlay = InCallTonePlayer.TONE_REORDER;
-            } else if (cause == DisconnectCause.CDMA_INTERCEPT) {
-                if (DBG) log("- need to play CDMA_INTERCEPT tone!");
-                toneToPlay = InCallTonePlayer.TONE_INTERCEPT;
-            } else if (cause == DisconnectCause.CDMA_DROP) {
-                if (DBG) log("- need to play CDMA_DROP tone!");
-                toneToPlay = InCallTonePlayer.TONE_CDMA_DROP;
-            } else if (cause == DisconnectCause.OUT_OF_SERVICE) {
-                if (DBG) log("- need to play OUT OF SERVICE tone!");
-                toneToPlay = InCallTonePlayer.TONE_OUT_OF_SERVICE;
-            } else if (cause == DisconnectCause.UNOBTAINABLE_NUMBER) {
-                if (DBG) log("- need to play TONE_UNOBTAINABLE_NUMBER tone!");
-                toneToPlay = InCallTonePlayer.TONE_UNOBTAINABLE_NUMBER;
-            } else if (cause == DisconnectCause.ERROR_UNSPECIFIED) {
-                if (DBG) log("- DisconnectCause is ERROR_UNSPECIFIED: play TONE_CALL_ENDED!");
-                toneToPlay = InCallTonePlayer.TONE_CALL_ENDED;
-            }
-        }
-
         // If we don't need to play BUSY or CONGESTION, then play the
         // "call ended" tone if this was a "regular disconnect" (i.e. a
         // normal call where one end or the other hung up) *and* this
diff --git a/src/com/android/services/telephony/CdmaConferenceController.java b/src/com/android/services/telephony/CdmaConferenceController.java
index dac0b0a..19b0430 100644
--- a/src/com/android/services/telephony/CdmaConferenceController.java
+++ b/src/com/android/services/telephony/CdmaConferenceController.java
@@ -18,6 +18,7 @@
 
 import android.os.Handler;
 import android.telecom.Connection;
+import android.telecom.DisconnectCause;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -51,7 +52,7 @@
                 }
 
                 @Override
-                public void onDisconnected(Connection c, int cause, String message) {
+                public void onDisconnected(Connection c, DisconnectCause disconnectCause) {
                     recalculateConference();
                 }
 
diff --git a/src/com/android/services/telephony/CdmaConnection.java b/src/com/android/services/telephony/CdmaConnection.java
index 60d32eb..a56205a 100644
--- a/src/com/android/services/telephony/CdmaConnection.java
+++ b/src/com/android/services/telephony/CdmaConnection.java
@@ -171,7 +171,7 @@
         mHandler.sendEmptyMessageDelayed(MSG_CALL_WAITING_MISSED, TIMEOUT_CALL_WAITING_MILLIS);
     }
 
-    private void hangupCallWaiting(int disconnectCause) {
+    private void hangupCallWaiting(int telephonyDisconnectCause) {
         Connection originalConnection = getOriginalConnection();
         if (originalConnection != null) {
             try {
@@ -179,7 +179,7 @@
             } catch (CallStateException e) {
                 Log.e(this, e, "Failed to hangup call waiting call");
             }
-            setDisconnected(disconnectCause, null);
+            setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(telephonyDisconnectCause));
         }
     }
 
diff --git a/src/com/android/services/telephony/DisconnectCauseUtil.java b/src/com/android/services/telephony/DisconnectCauseUtil.java
new file mode 100644
index 0000000..7b56902
--- /dev/null
+++ b/src/com/android/services/telephony/DisconnectCauseUtil.java
@@ -0,0 +1,332 @@
+/**
+ * Copyright (C) 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 com.android.services.telephony;
+
+import android.content.Context;
+import android.media.ToneGenerator;
+import android.telecom.DisconnectCause;
+
+import com.android.phone.PhoneGlobals;
+import com.android.phone.common.R;
+
+public class DisconnectCauseUtil {
+
+   /**
+    * Converts from a disconnect code in {@link android.telephony.DisconnectCause} into a more generic
+    * {@link android.telecom.DisconnectCause}.object, possibly populated with a localized message
+    * and tone.
+    *
+    * @param context The context.
+    * @param telephonyDisconnectCause The code for the reason for the disconnect.
+    */
+    public static DisconnectCause toTelecomDisconnectCause(int telephonyDisconnectCause) {
+        return toTelecomDisconnectCause(telephonyDisconnectCause, null /* reason */);
+    }
+
+   /**
+    * Converts from a disconnect code in {@link android.telephony.DisconnectCause} into a more generic
+    * {@link android.telecom.DisconnectCause}.object, possibly populated with a localized message
+    * and tone.
+    *
+    * @param context The context.
+    * @param telephonyDisconnectCause The code for the reason for the disconnect.
+    * @param reason Description of the reason for the disconnect, not intended for the user to see..
+    */
+    public static DisconnectCause toTelecomDisconnectCause(
+            int telephonyDisconnectCause, String reason) {
+        Context context = PhoneGlobals.getInstance();
+        return new DisconnectCause(
+                toTelecomDisconnectCauseCode(telephonyDisconnectCause),
+                toTelecomDisconnectCauseLabel(context, telephonyDisconnectCause),
+                toTelecomDisconnectCauseDescription(context, telephonyDisconnectCause),
+                reason,
+                toTelecomDisconnectCauseTone(telephonyDisconnectCause));
+    }
+
+    /**
+     * Convert the {@link android.telephony.DisconnectCause} disconnect code into a
+     * {@link android.telecom.DisconnectCause} disconnect code.
+     * @return The disconnect code as defined in {@link android.telecom.DisconnectCause}.
+     */
+    private static int toTelecomDisconnectCauseCode(int telephonyDisconnectCause) {
+        switch (telephonyDisconnectCause) {
+            case android.telephony.DisconnectCause.LOCAL:
+                return DisconnectCause.LOCAL;
+
+            case android.telephony.DisconnectCause.NORMAL:
+                return DisconnectCause.REMOTE;
+
+            case android.telephony.DisconnectCause.OUTGOING_CANCELED:
+                return DisconnectCause.CANCELED;
+
+            case android.telephony.DisconnectCause.INCOMING_MISSED:
+                return DisconnectCause.MISSED;
+
+            case android.telephony.DisconnectCause.INCOMING_REJECTED:
+                return DisconnectCause.REJECTED;
+
+            case android.telephony.DisconnectCause.BUSY:
+                return DisconnectCause.BUSY;
+
+            case android.telephony.DisconnectCause.CALL_BARRED:
+            case android.telephony.DisconnectCause.CDMA_ACCESS_BLOCKED:
+            case android.telephony.DisconnectCause.CDMA_NOT_EMERGENCY:
+            case android.telephony.DisconnectCause.CS_RESTRICTED:
+            case android.telephony.DisconnectCause.CS_RESTRICTED_EMERGENCY:
+            case android.telephony.DisconnectCause.CS_RESTRICTED_NORMAL:
+            case android.telephony.DisconnectCause.EMERGENCY_ONLY:
+            case android.telephony.DisconnectCause.FDN_BLOCKED:
+            case android.telephony.DisconnectCause.LIMIT_EXCEEDED:
+                return DisconnectCause.RESTRICTED;
+
+            case android.telephony.DisconnectCause.CDMA_ACCESS_FAILURE:
+            case android.telephony.DisconnectCause.CDMA_CALL_LOST:
+            case android.telephony.DisconnectCause.CDMA_DROP:
+            case android.telephony.DisconnectCause.CDMA_INTERCEPT:
+            case android.telephony.DisconnectCause.CDMA_LOCKED_UNTIL_POWER_CYCLE:
+            case android.telephony.DisconnectCause.CDMA_PREEMPTED:
+            case android.telephony.DisconnectCause.CDMA_REORDER:
+            case android.telephony.DisconnectCause.CDMA_RETRY_ORDER:
+            case android.telephony.DisconnectCause.CDMA_SO_REJECT:
+            case android.telephony.DisconnectCause.CONGESTION:
+            case android.telephony.DisconnectCause.ICC_ERROR:
+            case android.telephony.DisconnectCause.INVALID_CREDENTIALS:
+            case android.telephony.DisconnectCause.INVALID_NUMBER:
+            case android.telephony.DisconnectCause.LOST_SIGNAL:
+            case android.telephony.DisconnectCause.NO_PHONE_NUMBER_SUPPLIED:
+            case android.telephony.DisconnectCause.NUMBER_UNREACHABLE:
+            case android.telephony.DisconnectCause.OUTGOING_FAILURE:
+            case android.telephony.DisconnectCause.OUT_OF_NETWORK:
+            case android.telephony.DisconnectCause.OUT_OF_SERVICE:
+            case android.telephony.DisconnectCause.POWER_OFF:
+            case android.telephony.DisconnectCause.SERVER_ERROR:
+            case android.telephony.DisconnectCause.SERVER_UNREACHABLE:
+            case android.telephony.DisconnectCause.TIMED_OUT:
+            case android.telephony.DisconnectCause.UNOBTAINABLE_NUMBER:
+            case android.telephony.DisconnectCause.VOICEMAIL_NUMBER_MISSING:
+            case android.telephony.DisconnectCause.ERROR_UNSPECIFIED:
+                return DisconnectCause.ERROR;
+
+            case android.telephony.DisconnectCause.DIALED_MMI:
+            case android.telephony.DisconnectCause.EXITED_ECM:
+            case android.telephony.DisconnectCause.MMI:
+                return DisconnectCause.OTHER;
+
+            case android.telephony.DisconnectCause.NOT_VALID:
+            case android.telephony.DisconnectCause.NOT_DISCONNECTED:
+                return DisconnectCause.UNKNOWN;
+
+            default:
+                throw new IllegalStateException("Unrecognized Telephony DisconnectCause");
+        }
+    }
+
+    /**
+     * Returns a label for to the disconnect cause to be shown to the user.
+     */
+    private static CharSequence toTelecomDisconnectCauseLabel(
+            Context context, int telephonyDisconnectCause) {
+        if (context == null ) {
+            return "";
+        }
+
+        Integer resourceId = null;
+        switch (telephonyDisconnectCause) {
+            case android.telephony.DisconnectCause.BUSY:
+                resourceId = R.string.callFailed_userBusy;
+                break;
+
+            case android.telephony.DisconnectCause.CONGESTION:
+                resourceId = R.string.callFailed_congestion;
+                break;
+
+            case android.telephony.DisconnectCause.TIMED_OUT:
+                resourceId = R.string.callFailed_timedOut;
+                break;
+
+            case android.telephony.DisconnectCause.SERVER_UNREACHABLE:
+                resourceId = R.string.callFailed_server_unreachable;
+                break;
+
+            case android.telephony.DisconnectCause.NUMBER_UNREACHABLE:
+                resourceId = R.string.callFailed_number_unreachable;
+                break;
+
+            case android.telephony.DisconnectCause.INVALID_CREDENTIALS:
+                resourceId = R.string.callFailed_invalid_credentials;
+                break;
+
+            case android.telephony.DisconnectCause.SERVER_ERROR:
+                resourceId = R.string.callFailed_server_error;
+                break;
+
+            case android.telephony.DisconnectCause.OUT_OF_NETWORK:
+                resourceId = R.string.callFailed_out_of_network;
+                break;
+
+            case android.telephony.DisconnectCause.LOST_SIGNAL:
+            case android.telephony.DisconnectCause.CDMA_DROP:
+                resourceId = R.string.callFailed_noSignal;
+                break;
+
+            case android.telephony.DisconnectCause.LIMIT_EXCEEDED:
+                resourceId = R.string.callFailed_limitExceeded;
+                break;
+
+            case android.telephony.DisconnectCause.POWER_OFF:
+                resourceId = R.string.callFailed_powerOff;
+                break;
+
+            case android.telephony.DisconnectCause.ICC_ERROR:
+                resourceId = R.string.callFailed_simError;
+                break;
+
+            case android.telephony.DisconnectCause.OUT_OF_SERVICE:
+                resourceId = R.string.callFailed_outOfService;
+                break;
+
+            case android.telephony.DisconnectCause.INVALID_NUMBER:
+            case android.telephony.DisconnectCause.UNOBTAINABLE_NUMBER:
+                resourceId = R.string.callFailed_unobtainable_number;
+                break;
+
+            default:
+                break;
+        }
+        return resourceId == null ? "" : context.getResources().getString(resourceId);
+    }
+
+    /**
+     * Returns a description of the disconnect cause to be shown to the user.
+     */
+    private static CharSequence toTelecomDisconnectCauseDescription(
+            Context context, int telephonyDisconnectCause) {
+        if (context == null ) {
+            return "";
+        }
+
+        Integer resourceId = null;
+        switch (telephonyDisconnectCause) {
+            case android.telephony.DisconnectCause.CALL_BARRED:
+                resourceId = R.string.callFailed_cb_enabled;
+                break;
+
+            case android.telephony.DisconnectCause.FDN_BLOCKED:
+                resourceId = R.string.callFailed_fdn_only;
+                break;
+
+            case android.telephony.DisconnectCause.CS_RESTRICTED:
+                resourceId = R.string.callFailed_dsac_restricted;
+                break;
+
+            case android.telephony.DisconnectCause.CS_RESTRICTED_EMERGENCY:
+                resourceId = R.string.callFailed_dsac_restricted_emergency;
+                break;
+
+            case android.telephony.DisconnectCause.CS_RESTRICTED_NORMAL:
+                resourceId = R.string.callFailed_dsac_restricted_normal;
+                break;
+
+            case android.telephony.DisconnectCause.OUTGOING_FAILURE:
+                // We couldn't successfully place the call; there was some
+                // failure in the telephony layer.
+                // TODO: Need UI spec for this failure case; for now just
+                // show a generic error.
+                resourceId = R.string.incall_error_call_failed;
+                break;
+
+            case android.telephony.DisconnectCause.POWER_OFF:
+                // Radio is explictly powered off, presumably because the
+                // device is in airplane mode.
+                //
+                // TODO: For now this UI is ultra-simple: we simply display
+                // a message telling the user to turn off airplane mode.
+                // But it might be nicer for the dialog to offer the option
+                // to turn the radio on right there (and automatically retry
+                // the call once network registration is complete.)
+                resourceId = R.string.incall_error_power_off;
+                break;
+
+            case android.telephony.DisconnectCause.EMERGENCY_ONLY:
+                // Only emergency numbers are allowed, but we tried to dial
+                // a non-emergency number.
+                resourceId = R.string.incall_error_emergency_only;
+                break;
+
+            case android.telephony.DisconnectCause.OUT_OF_SERVICE:
+                // No network connection.
+                resourceId = R.string.incall_error_out_of_service;
+                break;
+
+            case android.telephony.DisconnectCause.NO_PHONE_NUMBER_SUPPLIED:
+                // The supplied Intent didn't contain a valid phone number.
+                // (This is rare and should only ever happen with broken
+                // 3rd-party apps.) For now just show a generic error.
+                resourceId = R.string.incall_error_no_phone_number_supplied;
+                break;
+
+            case android.telephony.DisconnectCause.VOICEMAIL_NUMBER_MISSING:
+                // TODO: Need to bring up the "Missing Voicemail Number" dialog, which
+                // will ultimately take us to the Call Settings.
+                resourceId = R.string.incall_error_missing_voicemail_number;
+                break;
+
+            case android.telephony.DisconnectCause.OUTGOING_CANCELED:
+                // We don't want to show any dialog for the canceled case since the call was
+                // either canceled by the user explicitly (end-call button pushed immediately)
+                // or some other app canceled the call and immediately issued a new CALL to
+                // replace it.
+            default:
+                break;
+        }
+        return resourceId == null ? "" : context.getResources().getString(resourceId);
+    }
+
+    /**
+     * Returns the tone to play for the disconnect cause, or UNKNOWN if none should be played.
+     */
+    private static int toTelecomDisconnectCauseTone(int telephonyDisconnectCause) {
+        switch (telephonyDisconnectCause) {
+            case android.telephony.DisconnectCause.BUSY:
+                return ToneGenerator.TONE_SUP_BUSY;
+
+            case android.telephony.DisconnectCause.CONGESTION:
+                return ToneGenerator.TONE_SUP_CONGESTION;
+
+            case android.telephony.DisconnectCause.CDMA_REORDER:
+                return ToneGenerator.TONE_CDMA_REORDER;
+
+            case android.telephony.DisconnectCause.CDMA_INTERCEPT:
+                return ToneGenerator.TONE_CDMA_ABBR_INTERCEPT;
+
+            case android.telephony.DisconnectCause.CDMA_DROP:
+            case android.telephony.DisconnectCause.OUT_OF_SERVICE:
+                return ToneGenerator.TONE_CDMA_CALLDROP_LITE;
+
+            case android.telephony.DisconnectCause.UNOBTAINABLE_NUMBER:
+                return ToneGenerator.TONE_SUP_ERROR;
+
+            case android.telephony.DisconnectCause.ERROR_UNSPECIFIED:
+            case android.telephony.DisconnectCause.LOCAL:
+            case android.telephony.DisconnectCause.NORMAL:
+                return ToneGenerator.TONE_PROP_PROMPT;
+
+            default:
+                return ToneGenerator.TONE_UNKNOWN;
+        }
+    }
+}
diff --git a/src/com/android/services/telephony/GsmConferenceController.java b/src/com/android/services/telephony/GsmConferenceController.java
index 759ddfa..58d031e 100644
--- a/src/com/android/services/telephony/GsmConferenceController.java
+++ b/src/com/android/services/telephony/GsmConferenceController.java
@@ -24,6 +24,7 @@
 
 import android.telecom.Conference;
 import android.telecom.Connection;
+import android.telecom.DisconnectCause;
 
 import com.android.internal.telephony.Call;
 
@@ -40,7 +41,7 @@
 
         /** ${inheritDoc} */
         @Override
-        public void onDisconnected(Connection c, int cause, String message) {
+        public void onDisconnected(Connection c, DisconnectCause disconnectCause) {
             recalculate();
         }
 
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 8b0cf87..79e7404 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -16,15 +16,16 @@
 
 package com.android.services.telephony;
 
+import android.content.Context;
 import android.net.Uri;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
 import android.telecom.AudioState;
 import android.telecom.Connection;
+import android.telecom.DisconnectCause;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneCapabilities;
-import android.telephony.DisconnectCause;
 
 import com.android.internal.telephony.Call;
 import com.android.internal.telephony.CallStateException;
@@ -190,7 +191,7 @@
     @Override
     public void onDisconnect() {
         Log.v(this, "onDisconnect");
-        hangup(DisconnectCause.LOCAL);
+        hangup(android.telephony.DisconnectCause.LOCAL);
     }
 
     @Override
@@ -208,7 +209,7 @@
     @Override
     public void onAbort() {
         Log.v(this, "onAbort");
-        hangup(DisconnectCause.LOCAL);
+        hangup(android.telephony.DisconnectCause.LOCAL);
     }
 
     @Override
@@ -237,7 +238,7 @@
     public void onReject() {
         Log.v(this, "onReject");
         if (isValidRingingCall()) {
-            hangup(DisconnectCause.INCOMING_REJECTED);
+            hangup(android.telephony.DisconnectCause.INCOMING_REJECTED);
         }
         super.onReject();
     }
@@ -385,7 +386,7 @@
         updateAddress();
     }
 
-    protected void hangup(int disconnectCause) {
+    protected void hangup(int telephonyDisconnectCode) {
         if (mOriginalConnection != null) {
             try {
                 // Hanging up a ringing call requires that we invoke call.hangup() as opposed to
@@ -412,7 +413,7 @@
 
         // Set state deliberately since we are going to close() and will no longer be
         // listening to state updates from mOriginalConnection
-        setDisconnected(disconnectCause, null);
+        setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(telephonyDisconnectCode));
         close();
     }
 
@@ -512,7 +513,8 @@
                     setRinging();
                     break;
                 case DISCONNECTED:
-                    setDisconnected(mOriginalConnection.getDisconnectCause(), null);
+                    setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(
+                            mOriginalConnection.getDisconnectCause()));
                     close();
                     break;
                 case DISCONNECTING:
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index ab6abc8..5935765 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -22,9 +22,9 @@
 import android.telecom.Connection;
 import android.telecom.ConnectionRequest;
 import android.telecom.ConnectionService;
+import android.telecom.DisconnectCause;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
-import android.telephony.DisconnectCause;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
@@ -68,8 +68,10 @@
         Uri handle = request.getAddress();
         if (handle == null) {
             Log.d(this, "onCreateOutgoingConnection, handle is null");
-            return Connection.createFailedConnection(DisconnectCause.NO_PHONE_NUMBER_SUPPLIED,
-                    "Handle is null");
+            return Connection.createFailedConnection(
+                    DisconnectCauseUtil.toTelecomDisconnectCause(
+                            android.telephony.DisconnectCause.NO_PHONE_NUMBER_SUPPLIED,
+                            "No phone number supplied"));
         }
 
         String scheme = handle.getScheme();
@@ -81,8 +83,10 @@
             number = phone.getVoiceMailNumber();
             if (TextUtils.isEmpty(number)) {
                 Log.d(this, "onCreateOutgoingConnection, no voicemail number set.");
-                return Connection.createFailedConnection(DisconnectCause.VOICEMAIL_NUMBER_MISSING,
-                        "Voicemail scheme provided but no voicemail number set.");
+                return Connection.createFailedConnection(
+                        DisconnectCauseUtil.toTelecomDisconnectCause(
+                                android.telephony.DisconnectCause.VOICEMAIL_NUMBER_MISSING,
+                                "Voicemail scheme provided but no voicemail number set."));
             }
 
             // Convert voicemail: to tel:
@@ -90,15 +94,19 @@
         } else {
             if (!PhoneAccount.SCHEME_TEL.equals(scheme)) {
                 Log.d(this, "onCreateOutgoingConnection, Handle %s is not type tel", scheme);
-                return Connection.createFailedConnection(DisconnectCause.INVALID_NUMBER,
-                        "Handle scheme is not type tel");
+                return Connection.createFailedConnection(
+                        DisconnectCauseUtil.toTelecomDisconnectCause(
+                                android.telephony.DisconnectCause.INVALID_NUMBER,
+                                "Handle scheme is not type tel"));
             }
 
             number = handle.getSchemeSpecificPart();
             if (TextUtils.isEmpty(number)) {
                 Log.d(this, "onCreateOutgoingConnection, unable to parse number");
-                return Connection.createFailedConnection(DisconnectCause.INVALID_NUMBER,
-                        "Unable to parse number");
+                return Connection.createFailedConnection(
+                        DisconnectCauseUtil.toTelecomDisconnectCause(
+                                android.telephony.DisconnectCause.INVALID_NUMBER,
+                                "Unable to parse number"));
             }
         }
 
@@ -108,8 +116,9 @@
         final Phone phone = getPhoneForAccount(request.getAccountHandle(), isEmergencyNumber);
         if (phone == null) {
             Log.d(this, "onCreateOutgoingConnection, phone is null");
-            return Connection.createFailedConnection(DisconnectCause.OUTGOING_FAILURE,
-                    "Phone is null");
+            return Connection.createFailedConnection(
+                    DisconnectCauseUtil.toTelecomDisconnectCause(
+                            android.telephony.DisconnectCause.OUTGOING_FAILURE, "Phone is null"));
         }
 
         int state = phone.getServiceState().getState();
@@ -125,15 +134,21 @@
                 case ServiceState.STATE_EMERGENCY_ONLY:
                     break;
                 case ServiceState.STATE_OUT_OF_SERVICE:
-                    return Connection.createFailedConnection(DisconnectCause.OUT_OF_SERVICE,
-                            "ServiceState.STATE_OUT_OF_SERVICE");
+                    return Connection.createFailedConnection(
+                            DisconnectCauseUtil.toTelecomDisconnectCause(
+                                    android.telephony.DisconnectCause.OUT_OF_SERVICE,
+                                    "ServiceState.STATE_OUT_OF_SERVICE"));
                 case ServiceState.STATE_POWER_OFF:
-                    return Connection.createFailedConnection(DisconnectCause.POWER_OFF,
-                            "ServiceState.STATE_POWER_OFF");
+                    return Connection.createFailedConnection(
+                            DisconnectCauseUtil.toTelecomDisconnectCause(
+                                    android.telephony.DisconnectCause.POWER_OFF,
+                                    "ServiceState.STATE_POWER_OFF"));
                 default:
                     Log.d(this, "onCreateOutgoingConnection, unknown service state: %d", state);
-                    return Connection.createFailedConnection(DisconnectCause.OUTGOING_FAILURE,
-                            "Unknown service state " + state);
+                    return Connection.createFailedConnection(
+                            DisconnectCauseUtil.toTelecomDisconnectCause(
+                                    android.telephony.DisconnectCause.OUTGOING_FAILURE,
+                                    "Unknown service state " + state));
             }
         }
 
@@ -141,7 +156,9 @@
                 createConnectionFor(phone, null, true /* isOutgoing */);
         if (connection == null) {
             return Connection.createFailedConnection(
-                    DisconnectCause.OUTGOING_FAILURE, "Invalid phone type");
+                    DisconnectCauseUtil.toTelecomDisconnectCause(
+                            android.telephony.DisconnectCause.OUTGOING_FAILURE,
+                            "Invalid phone type"));
         }
         connection.setAddress(handle, PhoneConstants.PRESENTATION_ALLOWED);
         connection.setInitializing();
@@ -162,8 +179,10 @@
                                 placeOutgoingConnection(connection, phone, request);
                             } else {
                                 Log.d(this, "onCreateOutgoingConnection, failed to turn on radio");
-                                connection.setDisconnected(DisconnectCause.POWER_OFF,
-                                        "Failed to turn on radio.");
+                                connection.setDisconnected(
+                                        DisconnectCauseUtil.toTelecomDisconnectCause(
+                                                android.telephony.DisconnectCause.POWER_OFF,
+                                                "Failed to turn on radio."));
                                 connection.destroy();
                             }
                         }
@@ -184,14 +203,18 @@
 
         Phone phone = getPhoneForAccount(request.getAccountHandle(), false);
         if (phone == null) {
-            return Connection.createFailedConnection(DisconnectCause.ERROR_UNSPECIFIED, null);
+            return Connection.createFailedConnection(
+                    DisconnectCauseUtil.toTelecomDisconnectCause(
+                            android.telephony.DisconnectCause.ERROR_UNSPECIFIED));
         }
 
         Call call = phone.getRingingCall();
         if (!call.getState().isRinging()) {
             Log.i(this, "onCreateIncomingConnection, no ringing call");
-            return Connection.createFailedConnection(DisconnectCause.INCOMING_MISSED,
-                    "Found no ringing call");
+            return Connection.createFailedConnection(
+                    DisconnectCauseUtil.toTelecomDisconnectCause(
+                            android.telephony.DisconnectCause.INCOMING_MISSED,
+                            "Found no ringing call"));
         }
 
         com.android.internal.telephony.Connection originalConnection =
@@ -231,24 +254,26 @@
             originalConnection = phone.dial(number, request.getVideoState());
         } catch (CallStateException e) {
             Log.e(this, e, "placeOutgoingConnection, phone.dial exception: " + e);
-            connection.setDisconnected(DisconnectCause.OUTGOING_FAILURE, e.getMessage());
+            connection.setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(
+                    android.telephony.DisconnectCause.OUTGOING_FAILURE,
+                    e.getMessage()));
             return;
         }
 
         if (originalConnection == null) {
-            int disconnectCause = DisconnectCause.OUTGOING_FAILURE;
-
+            int telephonyDisconnectCause = android.telephony.DisconnectCause.OUTGOING_FAILURE;
             // On GSM phones, null connection means that we dialed an MMI code
             if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_GSM) {
                 Log.d(this, "dialed MMI code");
-                disconnectCause = DisconnectCause.DIALED_MMI;
+                telephonyDisconnectCause = android.telephony.DisconnectCause.DIALED_MMI;
                 final Intent intent = new Intent(this, MMIDialogActivity.class);
                 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
                         Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
                 startActivity(intent);
             }
             Log.d(this, "placeOutgoingConnection, phone.dial returned null");
-            connection.setDisconnected(disconnectCause, "Connection is null");
+            connection.setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(
+                    telephonyDisconnectCause, "Connection is null"));
         } else {
             connection.setOriginalConnection(originalConnection);
         }