Merge "move and rename DcFailCause to DataFailCause"
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index bacb991..458c7de 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -2861,7 +2861,6 @@
 Lcom/android/internal/telephony/dataconnection/DataConnection;->mActiveState:Lcom/android/internal/telephony/dataconnection/DataConnection$DcActiveState;
 Lcom/android/internal/telephony/dataconnection/DataConnection;->mConnectionParams:Lcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams;
 Lcom/android/internal/telephony/dataconnection/DataConnection;->mDataRegState:I
-Lcom/android/internal/telephony/dataconnection/DataConnection;->mDcFailCause:Lcom/android/internal/telephony/dataconnection/DcFailCause;
 Lcom/android/internal/telephony/dataconnection/DataConnection;->mDct:Lcom/android/internal/telephony/dataconnection/DcTracker;
 Lcom/android/internal/telephony/dataconnection/DataConnection;->mDisconnectingErrorCreatingConnection:Lcom/android/internal/telephony/dataconnection/DataConnection$DcDisconnectionErrorCreatingConnection;
 Lcom/android/internal/telephony/dataconnection/DataConnection;->mDisconnectingState:Lcom/android/internal/telephony/dataconnection/DataConnection$DcDisconnectingState;
@@ -2872,10 +2871,8 @@
 Lcom/android/internal/telephony/dataconnection/DataConnection;->mNetworkInfo:Landroid/net/NetworkInfo;
 Lcom/android/internal/telephony/dataconnection/DataConnection;->mPhone:Lcom/android/internal/telephony/Phone;
 Lcom/android/internal/telephony/dataconnection/DataConnection;->mRilRat:I
-Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyAllDisconnectCompleted(Lcom/android/internal/telephony/dataconnection/DcFailCause;)V
 Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyAllOfConnected(Ljava/lang/String;)V
 Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyAllOfDisconnectDcRetrying(Ljava/lang/String;)V
-Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyConnectCompleted(Lcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams;Lcom/android/internal/telephony/dataconnection/DcFailCause;Z)V
 Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyDisconnectCompleted(Lcom/android/internal/telephony/dataconnection/DataConnection$DisconnectParams;Z)V
 Lcom/android/internal/telephony/dataconnection/DataConnection;->onConnect(Lcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams;)V
 Lcom/android/internal/telephony/dataconnection/DataConnection;->tearDownData(Ljava/lang/Object;)V
@@ -2884,22 +2881,6 @@
 Lcom/android/internal/telephony/dataconnection/DcController;->mDcListActiveByCid:Ljava/util/HashMap;
 Lcom/android/internal/telephony/dataconnection/DcController;->mDct:Lcom/android/internal/telephony/dataconnection/DcTracker;
 Lcom/android/internal/telephony/dataconnection/DcController;->mDcTesterDeactivateAll:Lcom/android/internal/telephony/dataconnection/DcTesterDeactivateAll;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->ACTIVATION_REJECT_GGSN:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->ACTIVATION_REJECT_UNSPECIFIED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->APN_TYPE_CONFLICT:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->INSUFFICIENT_RESOURCES:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->MISSING_UNKNOWN_APN:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->NSAPI_IN_USE:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->ONLY_IPV4_ALLOWED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->ONLY_IPV6_ALLOWED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->ONLY_SINGLE_BEARER_ALLOWED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->OPERATOR_BARRED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->PROTOCOL_ERRORS:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->SERVICE_OPTION_NOT_SUBSCRIBED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->SERVICE_OPTION_NOT_SUPPORTED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->SERVICE_OPTION_OUT_OF_ORDER:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->UNKNOWN_PDP_ADDRESS_TYPE:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->USER_AUTHENTICATION:Lcom/android/internal/telephony/dataconnection/DcFailCause;
 Lcom/android/internal/telephony/dataconnection/DcTracker$RecoveryAction;->isAggressiveRecovery(I)Z
 Lcom/android/internal/telephony/dataconnection/DcTracker;->cancelReconnectAlarm(Lcom/android/internal/telephony/dataconnection/ApnContext;)V
 Lcom/android/internal/telephony/dataconnection/DcTracker;->cleanUpAllConnections(Ljava/lang/String;)V
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index cfe134fd..388b5fb 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1398,9 +1398,9 @@
      * Example: "default"
      *
      * {@code ERROR_CODE_1} is an integer defined in
-     * {@link com.android.internal.telephony.dataconnection.DcFailCause DcFailure}
+     * {@link DataFailCause DcFailure}
      * Example:
-     * {@link com.android.internal.telephony.dataconnection.DcFailCause#MISSING_UNKNOWN_APN}
+     * {@link DataFailCause#MISSING_UNKNOWN_APN}
      *
      * {@code CARRIER_ACTION_IDX_1} is an integer defined in
      * {@link com.android.carrierdefaultapp.CarrierActionUtils CarrierActionUtils}
diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java
new file mode 100644
index 0000000..c6f7d0e
--- /dev/null
+++ b/telephony/java/android/telephony/DataFailCause.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2006 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.telephony;
+
+import android.content.Context;
+import android.os.PersistableBundle;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+
+/**
+ * Returned as the reason for a connection failure as defined
+ * by RIL_DataCallFailCause in ril.h and some local errors.
+ * @hide
+ */
+public enum DataFailCause {
+    NONE(0),
+
+    // This series of errors as specified by the standards
+    // specified in ril.h
+    OPERATOR_BARRED(0x08),                  /* no retry */
+    NAS_SIGNALLING(0x0E),
+    LLC_SNDCP(0x19),
+    INSUFFICIENT_RESOURCES(0x1A),
+    MISSING_UNKNOWN_APN(0x1B),              /* no retry */
+    UNKNOWN_PDP_ADDRESS_TYPE(0x1C),         /* no retry */
+    USER_AUTHENTICATION(0x1D),              /* no retry */
+    ACTIVATION_REJECT_GGSN(0x1E),           /* no retry */
+    ACTIVATION_REJECT_UNSPECIFIED(0x1F),
+    SERVICE_OPTION_NOT_SUPPORTED(0x20),     /* no retry */
+    SERVICE_OPTION_NOT_SUBSCRIBED(0x21),    /* no retry */
+    SERVICE_OPTION_OUT_OF_ORDER(0x22),
+    NSAPI_IN_USE(0x23),                     /* no retry */
+    REGULAR_DEACTIVATION(0x24),             /* possibly restart radio, based on config */
+    QOS_NOT_ACCEPTED(0x25),
+    NETWORK_FAILURE(0x26),
+    UMTS_REACTIVATION_REQ(0x27),
+    FEATURE_NOT_SUPP(0x28),
+    TFT_SEMANTIC_ERROR(0x29),
+    TFT_SYTAX_ERROR(0x2A),
+    UNKNOWN_PDP_CONTEXT(0x2B),
+    FILTER_SEMANTIC_ERROR(0x2C),
+    FILTER_SYTAX_ERROR(0x2D),
+    PDP_WITHOUT_ACTIVE_TFT(0x2E),
+    ONLY_IPV4_ALLOWED(0x32),                /* no retry */
+    ONLY_IPV6_ALLOWED(0x33),                /* no retry */
+    ONLY_SINGLE_BEARER_ALLOWED(0x34),
+    ESM_INFO_NOT_RECEIVED(0x35),
+    PDN_CONN_DOES_NOT_EXIST(0x36),
+    MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED(0x37),
+    MAX_ACTIVE_PDP_CONTEXT_REACHED(0x41),
+    UNSUPPORTED_APN_IN_CURRENT_PLMN(0x42),
+    INVALID_TRANSACTION_ID(0x51),
+    MESSAGE_INCORRECT_SEMANTIC(0x5F),
+    INVALID_MANDATORY_INFO(0x60),
+    MESSAGE_TYPE_UNSUPPORTED(0x61),
+    MSG_TYPE_NONCOMPATIBLE_STATE(0x62),
+    UNKNOWN_INFO_ELEMENT(0x63),
+    CONDITIONAL_IE_ERROR(0x64),
+    MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE(0x65),
+    PROTOCOL_ERRORS(0x6F),                  /* no retry */
+    APN_TYPE_CONFLICT(0x70),
+    INVALID_PCSCF_ADDR(0x71),
+    INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN(0x72),
+    EMM_ACCESS_BARRED(0x73),
+    EMERGENCY_IFACE_ONLY(0x74),
+    IFACE_MISMATCH(0x75),
+    COMPANION_IFACE_IN_USE(0x76),
+    IP_ADDRESS_MISMATCH(0x77),
+    IFACE_AND_POL_FAMILY_MISMATCH(0x78),
+    EMM_ACCESS_BARRED_INFINITE_RETRY(0x79),
+    AUTH_FAILURE_ON_EMERGENCY_CALL(0x7A),
+
+    // OEM sepecific error codes. To be used by OEMs when they don't
+    // want to reveal error code which would be replaced by ERROR_UNSPECIFIED
+    OEM_DCFAILCAUSE_1(0x1001),
+    OEM_DCFAILCAUSE_2(0x1002),
+    OEM_DCFAILCAUSE_3(0x1003),
+    OEM_DCFAILCAUSE_4(0x1004),
+    OEM_DCFAILCAUSE_5(0x1005),
+    OEM_DCFAILCAUSE_6(0x1006),
+    OEM_DCFAILCAUSE_7(0x1007),
+    OEM_DCFAILCAUSE_8(0x1008),
+    OEM_DCFAILCAUSE_9(0x1009),
+    OEM_DCFAILCAUSE_10(0x100A),
+    OEM_DCFAILCAUSE_11(0x100B),
+    OEM_DCFAILCAUSE_12(0x100C),
+    OEM_DCFAILCAUSE_13(0x100D),
+    OEM_DCFAILCAUSE_14(0x100E),
+    OEM_DCFAILCAUSE_15(0x100F),
+
+    // Local errors generated by Vendor RIL
+    // specified in ril.h
+    REGISTRATION_FAIL(-1),
+    GPRS_REGISTRATION_FAIL(-2),
+    SIGNAL_LOST(-3),                        /* no retry */
+    PREF_RADIO_TECH_CHANGED(-4),
+    RADIO_POWER_OFF(-5),                    /* no retry */
+    TETHERED_CALL_ACTIVE(-6),               /* no retry */
+    ERROR_UNSPECIFIED(0xFFFF),
+
+    // Errors generated by the Framework
+    // specified here
+    UNKNOWN(0x10000),
+    RADIO_NOT_AVAILABLE(0x10001),                   /* no retry */
+    UNACCEPTABLE_NETWORK_PARAMETER(0x10002),        /* no retry */
+    CONNECTION_TO_DATACONNECTIONAC_BROKEN(0x10003),
+    LOST_CONNECTION(0x10004),
+    RESET_BY_FRAMEWORK(0x10005);
+
+    private final int mErrorCode;
+    private static final HashMap<Integer, DataFailCause> sErrorCodeToFailCauseMap;
+    static {
+        sErrorCodeToFailCauseMap = new HashMap<Integer, DataFailCause>();
+        for (DataFailCause fc : values()) {
+            sErrorCodeToFailCauseMap.put(fc.getErrorCode(), fc);
+        }
+    }
+
+    /**
+     * Map of subId -> set of data call setup permanent failure for the carrier.
+     */
+    private static final HashMap<Integer, HashSet<DataFailCause>> sPermanentFailureCache =
+            new HashMap<>();
+
+    DataFailCause(int errorCode) {
+        mErrorCode = errorCode;
+    }
+
+    public int getErrorCode() {
+        return mErrorCode;
+    }
+
+    /**
+     * Returns whether or not the fail cause is a failure that requires a modem restart
+     *
+     * @param context device context
+     * @param subId subscription index
+     * @return true if the fail cause code needs platform to trigger a modem restart.
+     */
+    public boolean isRadioRestartFailure(Context context, int subId) {
+        CarrierConfigManager configManager = (CarrierConfigManager)
+                context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        if (configManager != null) {
+            PersistableBundle b = configManager.getConfigForSubId(subId);
+
+            if (b != null) {
+                if (this == REGULAR_DEACTIVATION
+                        && b.getBoolean(CarrierConfigManager
+                        .KEY_RESTART_RADIO_ON_PDP_FAIL_REGULAR_DEACTIVATION_BOOL)) {
+                    // This is for backward compatibility support. We need to continue support this
+                    // old configuration until it gets removed in the future.
+                    return true;
+                }
+                // Check the current configurations.
+                int[] causeCodes = b.getIntArray(CarrierConfigManager
+                        .KEY_RADIO_RESTART_FAILURE_CAUSES_INT_ARRAY);
+                if (causeCodes != null) {
+                    return Arrays.stream(causeCodes).anyMatch(i -> i == getErrorCode());
+                }
+            }
+        }
+
+        return false;
+    }
+
+    public boolean isPermanentFailure(Context context, int subId) {
+
+        synchronized (sPermanentFailureCache) {
+
+            HashSet<DataFailCause> permanentFailureSet = sPermanentFailureCache.get(subId);
+
+            // In case of cache miss, we need to look up the settings from carrier config.
+            if (permanentFailureSet == null) {
+                // Retrieve the permanent failure from carrier config
+                CarrierConfigManager configManager = (CarrierConfigManager)
+                        context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+                if (configManager != null) {
+                    PersistableBundle b = configManager.getConfigForSubId(subId);
+                    if (b != null) {
+                        String[] permanentFailureStrings = b.getStringArray(CarrierConfigManager.
+                                KEY_CARRIER_DATA_CALL_PERMANENT_FAILURE_STRINGS);
+
+                        if (permanentFailureStrings != null) {
+                            permanentFailureSet = new HashSet<>();
+                            for (String failure : permanentFailureStrings) {
+                                permanentFailureSet.add(DataFailCause.valueOf(failure));
+                            }
+                        }
+                    }
+                }
+
+                // If we are not able to find the configuration from carrier config, use the default
+                // ones.
+                if (permanentFailureSet == null) {
+                    permanentFailureSet = new HashSet<DataFailCause>() {
+                        {
+                            add(OPERATOR_BARRED);
+                            add(MISSING_UNKNOWN_APN);
+                            add(UNKNOWN_PDP_ADDRESS_TYPE);
+                            add(USER_AUTHENTICATION);
+                            add(ACTIVATION_REJECT_GGSN);
+                            add(SERVICE_OPTION_NOT_SUPPORTED);
+                            add(SERVICE_OPTION_NOT_SUBSCRIBED);
+                            add(NSAPI_IN_USE);
+                            add(ONLY_IPV4_ALLOWED);
+                            add(ONLY_IPV6_ALLOWED);
+                            add(PROTOCOL_ERRORS);
+                            add(RADIO_POWER_OFF);
+                            add(TETHERED_CALL_ACTIVE);
+                            add(RADIO_NOT_AVAILABLE);
+                            add(UNACCEPTABLE_NETWORK_PARAMETER);
+                            add(SIGNAL_LOST);
+                        }
+                    };
+                }
+
+                sPermanentFailureCache.put(subId, permanentFailureSet);
+            }
+
+            return permanentFailureSet.contains(this);
+        }
+    }
+
+    public boolean isEventLoggable() {
+        return (this == OPERATOR_BARRED) || (this == INSUFFICIENT_RESOURCES) ||
+                (this == UNKNOWN_PDP_ADDRESS_TYPE) || (this == USER_AUTHENTICATION) ||
+                (this == ACTIVATION_REJECT_GGSN) || (this == ACTIVATION_REJECT_UNSPECIFIED) ||
+                (this == SERVICE_OPTION_NOT_SUBSCRIBED) ||
+                (this == SERVICE_OPTION_NOT_SUPPORTED) ||
+                (this == SERVICE_OPTION_OUT_OF_ORDER) || (this == NSAPI_IN_USE) ||
+                (this == ONLY_IPV4_ALLOWED) || (this == ONLY_IPV6_ALLOWED) ||
+                (this == PROTOCOL_ERRORS) || (this == SIGNAL_LOST) ||
+                (this == RADIO_POWER_OFF) || (this == TETHERED_CALL_ACTIVE) ||
+                (this == UNACCEPTABLE_NETWORK_PARAMETER);
+    }
+
+    public static DataFailCause fromInt(int errorCode) {
+        DataFailCause fc = sErrorCodeToFailCauseMap.get(errorCode);
+        if (fc == null) {
+            fc = UNKNOWN;
+        }
+        return fc;
+    }
+}