Merge changes from topic "voice_metrics_android_s"

* changes:
  Add band mapping for GERAN and UTRAN
  Add new metrics to VoiceCallSession atom.
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index f7bbcbb..dbb3ecd 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -10581,6 +10581,32 @@
 
     // A random number used as the dimension field to pull multiple atoms.
     optional int32 dimension = 25;
+
+    // Signal strength at the end of the call. This value is applicable to both cellular and WiFi.
+    optional android.telephony.SignalStrengthEnum signal_strength_at_end = 26;
+
+    // Band at the end of the call. Value 0 is used if the band is unknown.
+    // See GeranBands, UtranBands and EutranBands in IRadio interface, depending on the RAT at
+    // the end of the call.
+    optional int32 band_at_end = 27;
+
+    // Time spent setting up the call in milliseconds.
+    // The time is measured from dial to ringing for outgoing calls, and from answer to connected
+    // for incoming calls.
+    optional int32 setup_duration_millis = 28;
+
+    // Main codec quality. The codec quality was equal to or greater than this value for at least
+    // 70% of the call.
+    optional android.telephony.CodecQuality main_codec_quality = 29;
+
+    // Whether video was enabled at any point during the call.
+    optional bool video_enabled = 30;
+
+    // Radio access technology (RAT) used when call is connected.
+    optional android.telephony.NetworkTypeEnum rat_at_connected = 31;
+
+    // Whether the call was a conference call (applicable only for calls over IMS).
+    optional bool is_multiparty = 32;
 }
 
 /**
diff --git a/core/proto/android/telephony/enums.proto b/core/proto/android/telephony/enums.proto
index 2546b51..b435fe7 100644
--- a/core/proto/android/telephony/enums.proto
+++ b/core/proto/android/telephony/enums.proto
@@ -99,7 +99,7 @@
     ROAMING_TYPE_ROAMING_INTERNATIONAL = 3;
 }
 
-// Signal strength levels, primarily used by android/telephony/SignalStrength.java.
+// Signal strength levels, as defined in android/telephony/SignalStrength.java.
 enum SignalStrengthEnum {
     SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
     SIGNAL_STRENGTH_POOR = 1;
@@ -267,4 +267,22 @@
     RECOVERY_ACTION_CLEANUP = 1;
     RECOVERY_ACTION_REREGISTER = 2;
     RECOVERY_ACTION_RADIO_RESTART = 3;
-}
\ No newline at end of file
+}
+
+// Codec quality
+enum CodecQuality {
+    /** Codec quality: unknown */
+    CODEC_QUALITY_UNKNOWN = 0;
+
+    /** Codec quality: narrowband */
+    CODEC_QUALITY_NARROWBAND = 1;
+
+    /** Codec quality: wideband */
+    CODEC_QUALITY_WIDEBAND = 2;
+
+    /** Codec quality: super-wideband */
+    CODEC_QUALITY_SUPER_WIDEBAND = 3;
+
+    /** Codec quality: fullband */
+    CODEC_QUALITY_FULLBAND = 4;
+}
diff --git a/telephony/java/android/telephony/AccessNetworkUtils.java b/telephony/java/android/telephony/AccessNetworkUtils.java
index 981ed450..7661a32 100644
--- a/telephony/java/android/telephony/AccessNetworkUtils.java
+++ b/telephony/java/android/telephony/AccessNetworkUtils.java
@@ -5,8 +5,11 @@
 import static android.telephony.ServiceState.DUPLEX_MODE_UNKNOWN;
 
 import android.telephony.AccessNetworkConstants.EutranBand;
+import android.telephony.AccessNetworkConstants.GeranBand;
+import android.telephony.AccessNetworkConstants.UtranBand;
 import android.telephony.ServiceState.DuplexMode;
 
+import java.util.Arrays;
 
 /**
  * Utilities to map between radio constants.
@@ -20,6 +23,9 @@
 
     public static final int INVALID_BAND = -1;
 
+    /** ISO country code of Japan. */
+    private static final String JAPAN_ISO_COUNTRY_CODE = "jp";
+
     /**
      * Gets the duplex mode for the given EUTRAN operating band.
      *
@@ -50,7 +56,7 @@
     /**
      * Gets the EUTRAN Operating band for a given downlink EARFCN.
      *
-     * <p>See 3GPP 36.101 sec 5.7.3-1 for calculation.
+     * <p>See 3GPP TS 36.101 clause 5.7.3-1 for calculation.
      *
      * @param earfcn The downlink EARFCN
      * @return Operating band number, or {@link #INVALID_BAND} if no corresponding band exists
@@ -198,4 +204,125 @@
 
         return INVALID_BAND;
     }
+
+    /**
+     * Gets the GERAN Operating band for a given ARFCN.
+     *
+     * <p>See 3GPP TS 45.005 clause 2 for calculation.
+     *
+     * @param arfcn The ARFCN
+     * @return Operating band number, or {@link #INVALID_BAND} if no corresponding band exists
+     */
+    public static int getOperatingBandForArfcn(int arfcn) {
+        if (arfcn >= 0 && arfcn <= 124) {
+            return GeranBand.BAND_E900;
+        } else if (arfcn >= 128 && arfcn <= 251) {
+            return GeranBand.BAND_850;
+        } else if (arfcn >= 259 && arfcn <= 293) {
+            return GeranBand.BAND_450;
+        } else if (arfcn >= 306 && arfcn <= 340) {
+            return GeranBand.BAND_480;
+        } else if (arfcn >= 438 && arfcn <= 511) {
+            return GeranBand.BAND_750;
+        } else if (arfcn >= 512 && arfcn <= 885) {
+            // ARFCN between 512 and 810 are also part of BAND_PCS1900.
+            // Returning BAND_DCS1800 in both cases.
+            return GeranBand.BAND_DCS1800;
+        } else if (arfcn >= 940 && arfcn <= 974) {
+            return GeranBand.BAND_ER900;
+        } else if (arfcn >= 975 && arfcn <= 1023) {
+            return GeranBand.BAND_E900;
+        }
+        return INVALID_BAND;
+    }
+
+    /**
+     * Gets the UTRAN Operating band for a given downlink UARFCN.
+     *
+     * <p>See 3GPP TS 25.101 clause 5.4.4 for calculation.
+     *
+     * @param uarfcn The downlink UARFCN
+     * @return Operating band number, or {@link #INVALID_BAND} if no corresponding band exists
+     */
+    public static int getOperatingBandForUarfcn(int uarfcn) {
+        // List of additional bands defined in TS 25.101.
+        int[] addlBand2 = {412, 437, 462, 487, 512, 537, 562, 587, 612, 637, 662, 687};
+        int[] addlBand4 = {1887, 1912, 1937, 1962, 1987, 2012, 2037, 2062, 2087};
+        int[] addlBand5 = {1007, 1012, 1032, 1037, 1062, 1087};
+        int[] addlBand6 = {1037, 1062};
+        int[] addlBand7 =
+                {2587, 2612, 2637, 2662, 2687, 2712, 2737, 2762, 2787, 2812, 2837, 2862,
+                2887, 2912};
+        int[] addlBand10 =
+                {3412, 3437, 3462, 3487, 3512, 3537, 3562, 3587, 3612, 3637, 3662, 3687};
+        int[] addlBand12 = {3932, 3957, 3962, 3987, 3992};
+        int[] addlBand13 = {4067, 4092};
+        int[] addlBand14 = {4167, 4192};
+        int[] addlBand19 = {787, 812, 837};
+        int[] addlBand25 =
+                {6292, 6317, 6342, 6367, 6392, 6417, 6442, 6467, 6492, 6517, 6542, 6567, 6592};
+        int[] addlBand26 = {5937, 5962, 5987, 5992, 6012, 6017, 6037, 6042, 6062, 6067, 6087};
+
+        if (uarfcn >= 10562 && uarfcn <= 10838) {
+            return UtranBand.BAND_1;
+        } else if ((uarfcn >= 9662 && uarfcn <= 9938)
+                || Arrays.binarySearch(addlBand2, uarfcn) >= 0) {
+            return UtranBand.BAND_2;
+        } else if (uarfcn >= 1162 && uarfcn <= 1513) {
+            return UtranBand.BAND_3;
+        } else if ((uarfcn >= 1537 && uarfcn <= 1738)
+                || Arrays.binarySearch(addlBand4, uarfcn) >= 0) {
+            return UtranBand.BAND_4;
+        } else if (uarfcn >= 4387 && uarfcn <= 4413) {
+            // Band 6 is a subset of band 5. Only Japan uses band 6 and Japan does not have band 5.
+            String country = TelephonyManager.getDefault().getNetworkCountryIso();
+            if (JAPAN_ISO_COUNTRY_CODE.compareToIgnoreCase(country) == 0) {
+                return UtranBand.BAND_6;
+            } else {
+                return UtranBand.BAND_5;
+            }
+        } else if ((uarfcn >= 4357 && uarfcn <= 4458)
+                || Arrays.binarySearch(addlBand5, uarfcn) >= 0) {
+            return UtranBand.BAND_5;
+        } else if (Arrays.binarySearch(addlBand6, uarfcn) >= 0) {
+            return UtranBand.BAND_6;
+        } else if ((uarfcn >= 2237 && uarfcn <= 2563)
+                || Arrays.binarySearch(addlBand7, uarfcn) >= 0) {
+            return UtranBand.BAND_7;
+        } else if (uarfcn >= 2937 && uarfcn <= 3088) {
+            return UtranBand.BAND_8;
+        } else if (uarfcn >= 9237 && uarfcn <= 9387) {
+            return UtranBand.BAND_9;
+        } else if ((uarfcn >= 3112 && uarfcn <= 3388)
+                || Arrays.binarySearch(addlBand10, uarfcn) >= 0) {
+            return UtranBand.BAND_10;
+        } else if (uarfcn >= 3712 && uarfcn <= 3787) {
+            return UtranBand.BAND_11;
+        } else if ((uarfcn >= 3842 && uarfcn <= 3903)
+                || Arrays.binarySearch(addlBand12, uarfcn) >= 0) {
+            return UtranBand.BAND_12;
+        } else if ((uarfcn >= 4017 && uarfcn <= 4043)
+                || Arrays.binarySearch(addlBand13, uarfcn) >= 0) {
+            return UtranBand.BAND_13;
+        } else if ((uarfcn >= 4117 && uarfcn <= 4143)
+                || Arrays.binarySearch(addlBand14, uarfcn) >= 0) {
+            return UtranBand.BAND_14;
+        } else if ((uarfcn >= 712 && uarfcn <= 763)
+                || Arrays.binarySearch(addlBand19, uarfcn) >= 0) {
+            return UtranBand.BAND_19;
+        } else if (uarfcn >= 4512 && uarfcn <= 4638) {
+            return UtranBand.BAND_20;
+        } else if (uarfcn >= 862 && uarfcn <= 912) {
+            return UtranBand.BAND_21;
+        } else if (uarfcn >= 4662 && uarfcn <= 5038) {
+            return UtranBand.BAND_22;
+        } else if ((uarfcn >= 5112 && uarfcn <= 5413)
+                || Arrays.binarySearch(addlBand25, uarfcn) >= 0) {
+            return UtranBand.BAND_25;
+        } else if ((uarfcn >= 5762 && uarfcn <= 5913)
+                || Arrays.binarySearch(addlBand26, uarfcn) >= 0) {
+            return UtranBand.BAND_26;
+        }
+        return INVALID_BAND;
+    }
 }