Merge "Add 5G NSA status to ServiceSate" am: c49ec8d1e7
am: c7b58deca1

Change-Id: Ic92ed92c9505b3eb20d7f41a20362829b4ab6192
diff --git a/telephony/java/android/telephony/NetworkRegistrationState.java b/telephony/java/android/telephony/NetworkRegistrationState.java
index 75e8eda..aee744f 100644
--- a/telephony/java/android/telephony/NetworkRegistrationState.java
+++ b/telephony/java/android/telephony/NetworkRegistrationState.java
@@ -70,6 +70,43 @@
     /** Registered on roaming network */
     public static final int REG_STATE_ROAMING               = 5;
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "NR_STATUS_",
+            value = {NR_STATUS_NONE, NR_STATUS_RESTRICTED, NR_STATUS_NOT_RESTRICTED,
+                    NR_STATUS_CONNECTED})
+    public @interface NRStatus {}
+
+    /**
+     * The device isn't camped on an LTE cell or the LTE cell doesn't support E-UTRA-NR
+     * Dual Connectivity(EN-DC).
+     * @hide
+     */
+    public static final int NR_STATUS_NONE = -1;
+
+    /**
+     * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) but
+     * either the use of dual connectivity with NR(DCNR) is restricted or NR is not supported by
+     * the selected PLMN.
+     * @hide
+     */
+    public static final int NR_STATUS_RESTRICTED = 1;
+
+    /**
+     * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) and both
+     * the use of dual connectivity with NR(DCNR) is not restricted and NR is supported by the
+     * selected PLMN.
+     * @hide
+     */
+    public static final int NR_STATUS_NOT_RESTRICTED = 2;
+
+    /**
+     * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) and
+     * also connected to at least one 5G cell as a secondary serving cell.
+     * @hide
+     */
+    public static final int NR_STATUS_CONNECTED = 3;
+
     /**
      * Supported service type
      * @hide
@@ -104,6 +141,9 @@
 
     private int mAccessNetworkTechnology;
 
+    @NRStatus
+    private int mNrStatus;
+
     private final int mRejectCause;
 
     private final boolean mEmergencyOnly;
@@ -154,6 +194,7 @@
         mAvailableServices = availableServices;
         mCellIdentity = cellIdentity;
         mEmergencyOnly = emergencyOnly;
+        mNrStatus = NR_STATUS_NONE;
     }
 
     /**
@@ -200,6 +241,7 @@
                 VoiceSpecificRegistrationStates.class.getClassLoader());
         mDataSpecificStates = source.readParcelable(
                 DataSpecificRegistrationStates.class.getClassLoader());
+        mNrStatus = source.readInt();
     }
 
     /**
@@ -213,6 +255,19 @@
     public @Domain int getDomain() { return mDomain; }
 
     /**
+     * @return the 5G NR connection status.
+     * @hide
+     */
+    public @NRStatus int getNrStatus() {
+        return mNrStatus;
+    }
+
+    /** @hide */
+    public void setNrStatus(@NRStatus int nrStatus) {
+        mNrStatus = nrStatus;
+    }
+
+    /**
      * @return The registration state.
      */
     public @RegState int getRegState() {
@@ -315,6 +370,19 @@
         return "Unknown reg state " + regState;
     }
 
+    private static String nrStatusToString(@NRStatus int nrStatus) {
+        switch (nrStatus) {
+            case NR_STATUS_RESTRICTED:
+                return "RESTRICTED";
+            case NR_STATUS_NOT_RESTRICTED:
+                return "NOT_RESTRICTED";
+            case NR_STATUS_CONNECTED:
+                return "CONNECTED";
+            default:
+                return "NONE";
+        }
+    }
+
     @Override
     public String toString() {
         return new StringBuilder("NetworkRegistrationState{")
@@ -330,6 +398,7 @@
                 .append(" cellIdentity=").append(mCellIdentity)
                 .append(" voiceSpecificStates=").append(mVoiceSpecificStates)
                 .append(" dataSpecificStates=").append(mDataSpecificStates)
+                .append(" nrStatus=").append(nrStatusToString(mNrStatus))
                 .append("}").toString();
     }
 
@@ -337,7 +406,7 @@
     public int hashCode() {
         return Objects.hash(mDomain, mTransportType, mRegState, mRoamingType,
                 mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
-                mCellIdentity, mVoiceSpecificStates, mDataSpecificStates);
+                mCellIdentity, mVoiceSpecificStates, mDataSpecificStates, mNrStatus);
     }
 
     @Override
@@ -359,7 +428,8 @@
                 && Arrays.equals(mAvailableServices, other.mAvailableServices)
                 && Objects.equals(mCellIdentity, other.mCellIdentity)
                 && Objects.equals(mVoiceSpecificStates, other.mVoiceSpecificStates)
-                && Objects.equals(mDataSpecificStates, other.mDataSpecificStates);
+                && Objects.equals(mDataSpecificStates, other.mDataSpecificStates)
+                && mNrStatus == other.mNrStatus;
     }
 
     @Override
@@ -375,6 +445,7 @@
         dest.writeParcelable(mCellIdentity, 0);
         dest.writeParcelable(mVoiceSpecificStates, 0);
         dest.writeParcelable(mDataSpecificStates, 0);
+        dest.writeInt(mNrStatus);
     }
 
     public static final Parcelable.Creator<NetworkRegistrationState> CREATOR =
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 0937b10..ab80e252 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -83,7 +83,45 @@
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef({DUPLEX_MODE_UNKNOWN, DUPLEX_MODE_FDD, DUPLEX_MODE_TDD})
+    @IntDef(prefix = "FREQUENCY_RANGE_",
+            value = {FREQUENCY_RANGE_UNKNOWN, FREQUENCY_RANGE_LOW, FREQUENCY_RANGE_MID,
+                    FREQUENCY_RANGE_HIGH, FREQUENCY_RANGE_MMWAVE})
+    public @interface FrequencyRange {}
+
+    /**
+     * Indicates frequency range is unknown.
+     * @hide
+     */
+    public static final int FREQUENCY_RANGE_UNKNOWN = -1;
+
+    /**
+     * Indicates the frequency range is below 1GHz.
+     * @hide
+     */
+    public static final int FREQUENCY_RANGE_LOW = 1;
+
+    /**
+     * Indicates the frequency range is between 1GHz to 3GHz.
+     * @hide
+     */
+    public static final int FREQUENCY_RANGE_MID = 2;
+
+    /**
+     * Indicates the frequency range is between 3GHz and 6GHz.
+     * @hide
+     */
+    public static final int FREQUENCY_RANGE_HIGH = 3;
+
+    /**
+     * Indicates the frequency range is above 6GHz (millimeter wave frequency).
+     * @hide
+     */
+    public static final int FREQUENCY_RANGE_MMWAVE = 4;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "DUPLEX_MODE_",
+            value = {DUPLEX_MODE_UNKNOWN, DUPLEX_MODE_FDD, DUPLEX_MODE_TDD})
     public @interface DuplexMode {}
 
     /**
@@ -283,6 +321,8 @@
     @UnsupportedAppUsage
     private boolean mIsUsingCarrierAggregation;
 
+    @FrequencyRange
+    private int mNrFrequencyRange;
     private int mChannelNumber;
     private int[] mCellBandwidths = new int[0];
 
@@ -375,6 +415,7 @@
         mLteEarfcnRsrpBoost = s.mLteEarfcnRsrpBoost;
         mNetworkRegistrationStates = s.mNetworkRegistrationStates == null ? null :
                 new ArrayList<>(s.mNetworkRegistrationStates);
+        mNrFrequencyRange = s.mNrFrequencyRange;
     }
 
     /**
@@ -406,6 +447,7 @@
         in.readList(mNetworkRegistrationStates, NetworkRegistrationState.class.getClassLoader());
         mChannelNumber = in.readInt();
         mCellBandwidths = in.createIntArray();
+        mNrFrequencyRange = in.readInt();
     }
 
     public void writeToParcel(Parcel out, int flags) {
@@ -433,6 +475,7 @@
         out.writeList(mNetworkRegistrationStates);
         out.writeInt(mChannelNumber);
         out.writeIntArray(mCellBandwidths);
+        out.writeInt(mNrFrequencyRange);
     }
 
     public int describeContents() {
@@ -792,7 +835,8 @@
                 mIsEmergencyOnly,
                 mIsUsingCarrierAggregation,
                 mLteEarfcnRsrpBoost,
-                mNetworkRegistrationStates);
+                mNetworkRegistrationStates,
+                mNrFrequencyRange);
     }
 
     @Override
@@ -823,7 +867,8 @@
                 && mIsUsingCarrierAggregation == s.mIsUsingCarrierAggregation)
                 && (mNetworkRegistrationStates == null ? s.mNetworkRegistrationStates == null :
                         s.mNetworkRegistrationStates != null &&
-                        mNetworkRegistrationStates.containsAll(s.mNetworkRegistrationStates));
+                        mNetworkRegistrationStates.containsAll(s.mNetworkRegistrationStates))
+                && mNrFrequencyRange == s.mNrFrequencyRange;
     }
 
     /**
@@ -958,6 +1003,7 @@
             .append(", mIsUsingCarrierAggregation=").append(mIsUsingCarrierAggregation)
             .append(", mLteEarfcnRsrpBoost=").append(mLteEarfcnRsrpBoost)
             .append(", mNetworkRegistrationStates=").append(mNetworkRegistrationStates)
+            .append(", mNrFrequencyRange=").append(mNrFrequencyRange)
             .append("}").toString();
     }
 
@@ -987,6 +1033,7 @@
         mIsUsingCarrierAggregation = false;
         mLteEarfcnRsrpBoost = 0;
         mNetworkRegistrationStates = new ArrayList<>();
+        mNrFrequencyRange = FREQUENCY_RANGE_UNKNOWN;
     }
 
     public void setStateOutOfService() {
@@ -1225,6 +1272,7 @@
         m.putInt("LteEarfcnRsrpBoost", mLteEarfcnRsrpBoost);
         m.putInt("ChannelNumber", mChannelNumber);
         m.putIntArray("CellBandwidths", mCellBandwidths);
+        m.putInt("mNrFrequencyRange", mNrFrequencyRange);
     }
 
     /** @hide */
@@ -1288,6 +1336,22 @@
         mIsUsingCarrierAggregation = ca;
     }
 
+    /**
+     * @return the frequency range of 5G NR.
+     * @hide
+     */
+    public @FrequencyRange int getNrFrequencyRange() {
+        return mNrFrequencyRange;
+    }
+
+    /**
+     * @param nrFrequencyRange the frequency range of 5G NR.
+     * @hide
+     */
+    public void setNrFrequencyRange(@FrequencyRange int nrFrequencyRange) {
+        mNrFrequencyRange = nrFrequencyRange;
+    }
+
     /** @hide */
     public int getLteEarfcnRsrpBoost() {
         return mLteEarfcnRsrpBoost;